package jnpf.engine.service.impl;

import com.baomidou.dynamic.datasource.annotation.DSTransactional;
import jnpf.base.Pagination;
import jnpf.base.UserInfo;
import jnpf.constant.MsgCode;
import jnpf.engine.entity.*;
import jnpf.engine.enums.*;
import jnpf.engine.model.flowbefore.*;
import jnpf.engine.model.flowcandidate.FlowCandidateListModel;
import jnpf.engine.model.flowcandidate.FlowCandidateUserModel;
import jnpf.engine.model.flowcandidate.FlowCandidateVO;
import jnpf.engine.model.flowengine.FlowModel;
import jnpf.engine.model.flowengine.FlowOperator;
import jnpf.engine.model.flowengine.FlowOperatordModel;
import jnpf.engine.model.flowengine.FlowUpdateNode;
import jnpf.engine.model.flowengine.shuntjson.childnode.ChildNode;
import jnpf.engine.model.flowengine.shuntjson.childnode.Properties;
import jnpf.engine.model.flowengine.shuntjson.nodejson.ChildNodeList;
import jnpf.engine.model.flowengine.shuntjson.nodejson.ConditionList;
import jnpf.engine.model.flowengine.shuntjson.nodejson.Custom;
import jnpf.engine.model.flowengine.shuntjson.nodejson.DateProperties;
import jnpf.engine.model.flowmessage.FlowMsgModel;
import jnpf.engine.model.flowmessage.FlowParameterModel;
import jnpf.engine.model.flowtask.*;
import jnpf.engine.model.flowtask.method.TaskChild;
import jnpf.engine.model.flowtask.method.TaskHandleIdStatus;
import jnpf.engine.model.flowtask.method.TaskOperatoUser;
import jnpf.engine.model.flowtask.method.TaskOperator;
import jnpf.engine.service.*;
import jnpf.engine.util.*;
import jnpf.exception.WorkFlowException;
import jnpf.job.WorkJobUtil;
import jnpf.job.WorkTimeoutJobUtil;
import jnpf.permission.constant.PermissionConst;
import jnpf.permission.entity.*;
import jnpf.util.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 流程引擎
 *
 * @author JNPF开发平台组
 * @version V3.2.0
 * @copyright 引迈信息技术有限公司
 * @date 2021年4月27日 上午9:18
 */
@Service
@Slf4j
public class FlowTaskNewServiceImpl implements FlowTaskNewService {

    @Autowired
    private UserProvider userProvider;
    @Autowired
    private ServiceAllUtil serviceUtil;
    @Autowired
    private FlowUserService flowUserService;
    @Autowired
    private FlowCandidatesService flowCandidatesService;
    @Autowired
    private FlowTaskNodeService flowTaskNodeService;
    @Autowired
    private FlowTaskOperatorService flowTaskOperatorService;
    @Autowired
    private FlowTaskOperatorRecordService flowTaskOperatorRecordService;
    @Autowired
    private FlowTaskCirculateService flowTaskCirculateService;
    @Autowired
    private FlowEngineService flowEngineService;
    @Autowired
    private FlowTaskService flowTaskService;
    @Autowired
    private FlowTaskUtil flowTaskUtil;
    @Autowired
    private RedisUtil redisUtil;
    @Autowired
    private FlowOperatorUserService flowOperatorUserService;
    @Autowired
    private FlowMsgUtil flowMsgUtil;
    @Autowired
    private FlowDelegateService flowDelegateService;

    @Autowired
    private WorkTimeoutJobUtil workTimeoutJobUtil;


    @Override
    public FlowTaskEntity saveIsAdmin(FlowModel flowModel) throws WorkFlowException {
        FlowTaskEntity entity = this.save(flowModel);
        return entity;
    }

    @Override
    @DSTransactional
    public FlowTaskEntity save(FlowModel flowModel) throws WorkFlowException {
        String flowId = flowModel.getFlowId();
        UserInfo userInfo = flowModel.getUserInfo();
        flowModel.setStatus(StringUtil.isNotEmpty(flowModel.getStatus()) ? flowModel.getStatus() : FlowStatusEnum.save.getMessage());
        String userId = StringUtil.isNotEmpty(flowModel.getUserId()) ? flowModel.getUserId() : userInfo.getUserId();
        //流程引擎
        FlowEngineEntity engine = flowEngineService.getInfo(flowId);
        boolean flag = flowModel.getId() == null;
        //流程实例
        String flowTitle = flowModel.getFlowTitle();
        FlowTaskEntity taskEntity = new FlowTaskEntity();
        if (!flag) {
            flowModel.setProcessId(flowModel.getId());
            taskEntity = flowTaskService.getInfo(flowModel.getProcessId());
            if (!FlowNature.ParentId.equals(taskEntity.getParentId())) {
                flowModel.setParentId(taskEntity.getParentId());
                flowTitle += "(子流程)";
                flowModel.setIsAsync(FlowNature.ChildAsync.equals(taskEntity.getIsAsync()));
            }
        }
        ChildNode childNodeAll = JsonUtil.getJsonToBean(engine.getFlowTemplateJson(), ChildNode.class);
        Properties properties = childNodeAll.getProperties();
        Map<String, Object> data = flowModel.getFormData() != null ? flowModel.getFormData() : new HashMap<>();
        data.put("@flowFullName", engine.getFullName());
        data.put("@flowFullCode", engine.getEnCode());
        data.put("@launchUserName", userInfo.getUserName());
        data.put("@launchTime", DateUtil.daFormat(new Date()));
        if (FlowStatusEnum.save.getMessage().equals(flowModel.getStatus())) {
            flowTitle = engine.getFullName() + (!FlowNature.ParentId.equals(flowModel.getParentId()) ? "(子流程)" : "");
        } else {
            if (!FlowNature.TitleType.equals(properties.getTitleType())) {
                flowTitle = FlowJsonUtil.field(properties.getTitleContent(), data, "1");
            }
        }
        flowModel.setFlowTitle(flowTitle);
        flowTaskUtil.task(taskEntity, engine, flowModel, userId);
        //更新流程任务
        if (flag) {
            flowTaskService.create(taskEntity);
        } else {
            flowTaskService.update(taskEntity);
        }
        return taskEntity;
    }

    @Override
    @DSTransactional
    public void submit(FlowModel flowModel) throws WorkFlowException {
        FlowContextHolder.initEvent();
        UserInfo userInfo = flowModel.getUserInfo();
        flowModel.setStatus(FlowStatusEnum.submit.getMessage());
        //流程实例
        FlowTaskEntity flowTask = saveIsAdmin(flowModel);
        //发起用户信息
        flowTaskUtil.flowUser(flowTask);
        FlowEngineEntity engine = flowEngineService.getInfo(flowTask.getFlowId());
        flowTask.setStartTime(new Date());
        flowModel.setOperatorId(FlowNature.ParentId);
        //流程节点
        List<FlowTaskNodeEntity> taskNodeList = new LinkedList<>();
        //流程经办
        List<FlowTaskOperatorEntity> operatorList = new LinkedList<>();
        //流程表单Json
        String formDataJson = flowTask.getFlowTemplateJson();
        ChildNode childNodeAll = JsonUtil.getJsonToBean(formDataJson, ChildNode.class);
        //获取流程节点
        List<ChildNodeList> nodeListAll = new LinkedList<>();
        List<ConditionList> conditionListAll = new LinkedList<>();
        FlowUpdateNode updateNode = FlowUpdateNode.builder().childNodeAll(childNodeAll).nodeListAll(nodeListAll).taskNodeList(taskNodeList).conditionListAll(conditionListAll).flowTask(flowTask).userInfo(userInfo).isSubmit(true).build();
        flowTaskUtil.updateNodeList(updateNode);
        //获取下一个节点
        Optional<FlowTaskNodeEntity> first = taskNodeList.stream().filter(t -> FlowNature.NodeStart.equals(t.getNodeType())).findFirst();
        if (!first.isPresent()) {
            throw new WorkFlowException(MsgCode.COD001.get());
        }
        //保存节点
        FlowTaskNodeEntity startNode = first.get();
        FlowNodeListModel nodeListModel = new FlowNodeListModel(taskNodeList, flowModel, true, startNode, 1L);
        flowTaskUtil.nodeListAll(nodeListModel);
        List<String> nodeList = Arrays.asList(startNode.getNodeNext().split(","));
        ChildNodeList start = JsonUtil.getJsonToBean(startNode.getNodePropertyJson(), ChildNodeList.class);
        //审批记录
        FlowTaskOperatorEntity operator = new FlowTaskOperatorEntity();
        operator.setTaskId(flowTask.getId());
        operator.setNodeCode(start.getCustom().getNodeId());
        FlowTaskOperatorRecordEntity operatorRecord = new FlowTaskOperatorRecordEntity();
        //审批数据赋值
        FlowOperatordModel flowOperatordModel = FlowOperatordModel.builder().status(FlowRecordEnum.submit.getCode()).flowModel(flowModel).userId(userInfo.getUserId()).operator(operator).build();
        flowTaskUtil.operatorRecord(operatorRecord, flowOperatordModel);
        flowTaskOperatorRecordService.create(operatorRecord);
        //获取下一审批人
        List<ChildNodeList> nextOperatorList = nodeListAll.stream().filter(t -> nodeList.contains(t.getCustom().getNodeId())).collect(Collectors.toList());
        Map<String, List<String>> asyncTaskList = new HashMap<>();
        FlowOperator flowOperator = FlowOperator.builder().operatorListAll(operatorList).flowModel(flowModel).flowTask(flowTask).nodeList(nextOperatorList).taskNodeListAll(taskNodeList).userInfo(userInfo).asyncTaskList(asyncTaskList).build();
        Map<String, List<String>> nodeIdAll = flowTaskUtil.nextOperator(flowOperator);
        Map<String, List<FlowTaskOperatorEntity>> operatorMap = operatorList.stream().collect(Collectors.groupingBy(FlowTaskOperatorEntity::getTaskNodeId));
        for (ChildNodeList childNodeList : nextOperatorList) {
            Properties properties = childNodeList.getProperties();
            boolean counterSign = FlowNature.ImproperApprover.equals(properties.getCounterSign());
            if (counterSign && StringUtil.isEmpty(flowModel.getFreeApproverUserId())) {
                List<FlowTaskOperatorEntity> listAll = operatorMap.get(childNodeList.getTaskNodeId()) != null ? operatorMap.get(childNodeList.getTaskNodeId()) : new LinkedList<>();
                flowOperatorUserService.create(JsonUtil.getJsonToList(listAll, FlowOperatorUserEntity.class));
            }
        }
        //过滤依次审批人
        flowTaskUtil.improperApproverUser(operatorList, taskNodeList, start, null);
        flowTaskOperatorService.create(operatorList);
        //获取抄送人
        List<FlowTaskCirculateEntity> circulateList = new LinkedList<>();
        flowTaskUtil.circulateList(start, circulateList, flowModel);
        flowTaskCirculateService.create(circulateList);
        //修改选择分支没有走过的节点
        List<String> nodeCodeList = nextOperatorList.stream().map(t -> t.getCustom().getNodeId()).collect(Collectors.toList());
        flowTaskUtil.branchTaskNode(nodeCodeList, taskNodeList, operatorList);
        //更新关联同步子流程id
        for (String nodeId : nodeIdAll.keySet()) {
            FlowTaskNodeEntity entity = flowTaskNodeService.getInfo(nodeId);
            if (entity != null) {
                ChildNodeList childNodeList = JsonUtil.getJsonToBean(entity.getNodePropertyJson(), ChildNodeList.class);
                childNodeList.getCustom().setTaskId(nodeIdAll.get(nodeId));
                entity.setNodePropertyJson(JsonUtil.getObjectToString(childNodeList));
                flowTaskNodeService.update(entity);
            }
        }
        //更新关联异步子流程id
        for (String nodeId : asyncTaskList.keySet()) {
            FlowTaskNodeEntity entity = flowTaskNodeService.getInfo(nodeId);
            if (entity != null) {
                ChildNodeList childNodeList = JsonUtil.getJsonToBean(entity.getNodePropertyJson(), ChildNodeList.class);
                childNodeList.getCustom().setAsyncTaskList(asyncTaskList.get(nodeId));
                entity.setNodePropertyJson(JsonUtil.getObjectToString(childNodeList));
                flowTaskNodeService.update(entity);
            }
        }
        //提交记录
        boolean request = flowTaskUtil.requestData(start, flowModel.getFormData());
        if (request) {
            throw new WorkFlowException(MsgCode.WF001.get());
        }
        //定时器
        FlowTaskOperatorEntity startOperator = new FlowTaskOperatorEntity();
        startOperator.setTaskId(start.getTaskId());
        startOperator.setTaskNodeId(start.getTaskNodeId());
        DateProperties timer = start.getTimer();
        List<Date> dateList = new LinkedList<>();
        if (timer.getTime()) {
            Date date = new Date();
            date = DateUtil.dateAddDays(date, timer.getDay());
            date = DateUtil.dateAddHours(date, timer.getHour());
            date = DateUtil.dateAddMinutes(date, timer.getMinute());
            date = DateUtil.dateAddSeconds(date, timer.getSecond());
            dateList.add(date);
        }
        startOperator.setDescription(JsonUtil.getObjectToString(dateList));
        List<FlowTaskOperatorEntity> operatorAll = flowTaskUtil.timer(startOperator, taskNodeList, operatorList);
        for (FlowTaskOperatorEntity operatorTime : operatorAll) {
            List<Date> dateAll = JsonUtil.getJsonToList(operatorTime.getDescription(), Date.class);
            if (dateAll.size() > 0) {
                Date max = Collections.max(dateAll);
                operatorTime.setCreatorTime(max);
            }
            flowTaskOperatorService.update(operatorTime);
        }
        //开始事件
        flowMsgUtil.event(1, start, operatorRecord, flowModel);
        //自动审批
        FlowApproveModel approveModel = FlowApproveModel.builder().operatorList(operatorList).taskNodeList(taskNodeList).flowTask(flowTask).flowModel(flowModel).isSubmit(true).build();
        flowTaskUtil.approve(approveModel);
        //更新流程节点
        if (StringUtil.isEmpty(flowTask.getThisStepId())) {
            flowTaskUtil.getNextStepId(nextOperatorList, flowTask, flowModel);
        }
        boolean isEnd = nodeList.contains(FlowNature.NodeEnd);
        FlowTaskEntity flowSubmit = null;
        if (isEnd) {
            flowTaskUtil.endround(flowTask, nodeListAll.get(0), flowModel);
        } else {
            flowSubmit = flowTaskService.getInfoSubmit(flowTask.getId());
            flowSubmit.setStartTime(flowTask.getStartTime());
            if (StringUtil.isEmpty(flowSubmit.getThisStepId())) {
                flowSubmit.setThisStep(flowTask.getThisStep());
                flowSubmit.setThisStepId(flowTask.getThisStepId());
                flowSubmit.setCompletion(flowTask.getCompletion());
            }
        }
        flowTaskService.update(isEnd ? flowTask : flowSubmit);
        //保存节点数据
        startNode.setDraftData(flowTask.getFlowFormContentJson());
        flowTaskNodeService.update(startNode);
        //发送消息
        FlowMsgModel flowMsgModel = new FlowMsgModel();
        flowMsgModel.setCirculateList(circulateList);
        flowMsgModel.setNodeList(taskNodeList);
        flowMsgModel.setOperatorList(operatorList);
        flowMsgModel.setData(flowModel.getFormData());
        flowMsgModel.setFlowModel(flowModel);
        flowMsgModel.setTaskEntity(flowTask);
        flowMsgModel.setCopy(true);
        flowMsgModel.setCirculateList(circulateList);
        if (isEnd) {
            flowMsgModel.setTaskNodeEntity(startNode);
        }
        List<FlowParameterModel> parameterModels = FlowContextHolder.getAllEvent();
        for (FlowParameterModel model : parameterModels) {
            serviceUtil.infoToId(model.getInterId(), model.getParameterMap());
        }
        FlowContextHolder.clearEvent();
        flowMsgModel.setEngine(engine);
//        flowMsgUtil.message(flowMsgModel);
        //定时器
        WorkJobModel workJobModel = new WorkJobModel(flowModel.getProcessId(), flowMsgModel, userInfo);
        WorkJobUtil.insertRedis(workJobModel, redisUtil);
        //超时
        for (FlowTaskOperatorEntity operatorOne : operatorList) {
            WorkTimeoutJobModel workTimeoutJobModel = WorkTimeoutJobModel.builder().flowModel(flowModel)
                    .taskId(flowTask.getId()).taskNodeId(operatorOne.getTaskNodeId()).taskNodeOperatorId(operatorOne.getId()).operatorEntity(operatorOne)
                    .tenantId(userInfo.getTenantId()).tenantDbConnectionString(userInfo.getTenantDbConnectionString()).build();
            workTimeoutJobUtil.insertRedis(workTimeoutJobModel, redisUtil);
        }
    }

    @Override
    public void audit(String id, FlowModel flowModel) throws WorkFlowException {
        FlowTaskOperatorEntity operator = flowTaskOperatorService.getInfo(id);
        if (operator != null) {
            if (FlowNature.ProcessCompletion.equals(operator.getCompletion())) {
                FlowTaskEntity flowTask = flowTaskService.getInfo(operator.getTaskId());
                this.audit(flowTask, operator, flowModel);
            }
        }
    }

    @Override
    @DSTransactional
    public void audit(FlowTaskEntity flowTask, FlowTaskOperatorEntity operator, FlowModel flowModel) throws WorkFlowException {
        UserInfo userInfo = flowModel.getUserInfo();
        FlowEngineEntity engine = flowEngineService.getInfo(flowTask.getFlowId());
        //判断是否审批过
        if (!FlowNature.ProcessCompletion.equals(operator.getCompletion())) {
            throw new WorkFlowException(MsgCode.WF005.get());
        }
        boolean isOperator = StringUtil.isNotEmpty(operator.getId());
        flowTaskUtil.auditTaskNode(engine, flowTask, operator, flowModel);
        flowModel.setOperatorId(operator.getId());
        String userId = StringUtil.isNotEmpty(flowModel.getUserId()) ? flowModel.getUserId() : userInfo.getUserId();
        //流程所有节点
        List<FlowTaskNodeEntity> flowTaskNodeAll = flowTaskNodeService.getList(flowTask.getId());
        List<FlowTaskNodeEntity> taskNodeList = flowTaskNodeAll.stream().filter(t -> FlowNodeEnum.Process.getCode().equals(t.getState())).collect(Collectors.toList());
        //当前节点
        Optional<FlowTaskNodeEntity> first = taskNodeList.stream().filter(m -> m.getId().equals(operator.getTaskNodeId())).findFirst();
        if (!first.isPresent()) {
            throw new WorkFlowException(MsgCode.COD001.get());
        }
        FlowTaskNodeEntity taskNode = first.get();
        //当前节点属性
        ChildNodeList nodeModel = JsonUtil.getJsonToBean(taskNode.getNodePropertyJson(), ChildNodeList.class);
        boolean request = flowTaskUtil.requestData(nodeModel, flowModel.getFormData());
        if (request) {
            throw new WorkFlowException(MsgCode.WF001.get());
        }
        //同意记录
        FlowTaskOperatorRecordEntity operatorRecord = new FlowTaskOperatorRecordEntity();
        //审批数据赋值
        FlowOperatordModel flowOperatordModel = FlowOperatordModel.builder().status(FlowRecordEnum.audit.getCode()).flowModel(flowModel).userId(userId).operator(operator).build();
        flowTaskUtil.operatorRecord(operatorRecord, flowOperatordModel);
        //子流程不新增流转记录
        if (!flowModel.getIsAsync()) {
            flowTaskOperatorRecordService.create(operatorRecord);
        }
        //修改或签、会签经办数据
        TaskHandleIdStatus handleIdStatus = new TaskHandleIdStatus();
        handleIdStatus.setStatus(1);
        handleIdStatus.setNodeModel(nodeModel);
        handleIdStatus.setUserInfo(userInfo);
        handleIdStatus.setTaskNodeList(taskNodeList);
        handleIdStatus.setFlowModel(flowModel);
        flowTaskUtil.handleIdStatus(operator, handleIdStatus);
        //更新流当前程经办状态
        if (isOperator) {
            flowTaskOperatorService.update(operator);
        }
        //更新下一节点
        List<FlowTaskOperatorEntity> operatorList = new LinkedList<>();
        //获取下一审批人
        List<FlowTaskNodeEntity> nextNode = taskNodeList.stream().filter(t -> taskNode.getNodeNext().contains(t.getNodeCode())).collect(Collectors.toList());
        List<ChildNodeList> nextOperatorList = new LinkedList<>();
        List<FlowTaskNodeEntity> result = flowTaskUtil.isNextAll(taskNodeList, nextNode, taskNode, flowModel);
        for (FlowTaskNodeEntity entity : result) {
            ChildNodeList node = JsonUtil.getJsonToBean(entity.getNodePropertyJson(), ChildNodeList.class);
            nextOperatorList.add(node);
        }
        //节点事件
        flowMsgUtil.event(4, nodeModel, operatorRecord, flowModel);
        Map<String, Object> data = flowTaskUtil.createData(engine, flowTask, flowModel);
        flowTaskUtil.candidateList(flowModel, taskNodeList, operator);
        //下个节点
        Map<String, List<String>> asyncTaskList = new HashMap<>();
        FlowOperator flowOperator = FlowOperator.builder().operatorListAll(operatorList).flowModel(flowModel).flowTask(flowTask).nodeList(nextOperatorList).taskNodeListAll(taskNodeList).userInfo(userInfo).asyncTaskList(asyncTaskList).build();
        Map<String, List<String>> nodeIdAll = flowTaskUtil.nextOperator(flowOperator);
        Map<String, List<FlowTaskOperatorEntity>> operatorMap = operatorList.stream().collect(Collectors.groupingBy(FlowTaskOperatorEntity::getTaskNodeId));
        for (ChildNodeList childNodeList : nextOperatorList) {
            Properties properties = childNodeList.getProperties();
            boolean counterSign = FlowNature.ImproperApprover.equals(properties.getCounterSign());
            if (counterSign && StringUtil.isEmpty(flowModel.getFreeApproverUserId())) {
                List<FlowTaskOperatorEntity> listAll = operatorMap.get(childNodeList.getTaskNodeId()) != null ? operatorMap.get(childNodeList.getTaskNodeId()) : new LinkedList<>();
                flowOperatorUserService.create(JsonUtil.getJsonToList(listAll, FlowOperatorUserEntity.class));
            }
        }
        //过滤依次审批人
        flowTaskUtil.improperApproverUser(operatorList, taskNodeList, nodeModel, operator);
        flowTaskOperatorService.create(operatorList);
        //修改选择分支没有走过的节点
        List<String> nodeCodeList = result.stream().map(FlowTaskNodeEntity::getNodeCode).collect(Collectors.toList());
        flowTaskUtil.branchTaskNode(nodeCodeList, taskNodeList, operatorList);
        //更新流程节点
        flowTaskUtil.getNextStepId(nextOperatorList, flowTask, flowModel);
        flowTask.setFlowFormContentJson(JsonUtil.getObjectToString(data));
        flowTask.setTaskNodeId(null);
        flowTask.setCompletion(FlowNature.NodeEnd.equals(flowTask.getThisStepId()) ? FlowNature.Progress : flowTask.getCompletion());
        if (StringUtil.isNotEmpty(flowTask.getThisStepId())) {
            flowTaskService.update(flowTask);
        }
        //更新关联同步子流程id
        for (String nodeId : nodeIdAll.keySet()) {
            FlowTaskNodeEntity entity = flowTaskNodeService.getInfo(nodeId);
            if (entity != null) {
                ChildNodeList childNodeList = JsonUtil.getJsonToBean(entity.getNodePropertyJson(), ChildNodeList.class);
                childNodeList.getCustom().setTaskId(nodeIdAll.get(nodeId));
                entity.setNodePropertyJson(JsonUtil.getObjectToString(childNodeList));
                flowTaskNodeService.update(entity);
            }
        }
        //更新关联异步子流程id
        for (String nodeId : asyncTaskList.keySet()) {
            FlowTaskNodeEntity entity = flowTaskNodeService.getInfo(nodeId);
            if (entity != null) {
                ChildNodeList childNodeList = JsonUtil.getJsonToBean(entity.getNodePropertyJson(), ChildNodeList.class);
                childNodeList.getCustom().setAsyncTaskList(asyncTaskList.get(nodeId));
                entity.setNodePropertyJson(JsonUtil.getObjectToString(childNodeList));
                flowTaskNodeService.update(entity);
            }
        }
        //定时器
        List<FlowTaskOperatorEntity> operatorAll = flowTaskUtil.timer(operator, taskNodeList, operatorList);
        for (FlowTaskOperatorEntity operatorTime : operatorAll) {
            List<Date> dateAll = JsonUtil.getJsonToList(operatorTime.getDescription(), Date.class);
            if (dateAll.size() > 0) {
                Date max = Collections.max(dateAll);
                operatorTime.setCreatorTime(max);
            }
            flowTaskOperatorService.update(operatorTime);
        }
        //更新节点接收时间
        flowTaskUtil.taskCreatTime(operatorList);
        //获取抄送人
        List<FlowTaskCirculateEntity> circulateList = new LinkedList<>();
        flowTaskUtil.circulateList(nodeModel, circulateList, flowModel);
        flowTaskCirculateService.create(circulateList);
        //发送消息
        FlowMsgModel flowMsgModel = new FlowMsgModel();
        flowMsgModel.setApprove(FlowNature.AuditCompletion.equals(taskNode.getCompletion()));
        flowMsgModel.setCopy(true);
        flowMsgModel.setNodeList(taskNodeList);
        List<FlowTaskOperatorEntity> operatorListAll = new ArrayList() {{
            addAll(operatorList);
        }};
        flowMsgModel.setOperatorList(operatorListAll);
        flowMsgModel.setCirculateList(circulateList);
        flowMsgModel.setData(flowModel.getFormData());
        flowMsgModel.setTaskNodeEntity(taskNode);
        flowMsgModel.setTaskEntity(flowTask);
        flowMsgModel.setEngine(engine);
        flowMsgModel.setTitle(StringUtil.isNotEmpty(flowModel.getFreeApproverUserId()) ? "已被【指派】" : "");
        FlowTaskOperatorRecordEntity taskOperatorRecord = new FlowTaskOperatorRecordEntity();
        taskOperatorRecord.setHandleId(userInfo.getUserId());
        flowMsgModel.setFlowModel(flowModel);
//        flowMsgUtil.message(flowMsgModel);
        //定时器
        WorkJobModel workJobModel = new WorkJobModel(StringUtil.isNotEmpty(operator.getId()) ? operator.getId() : RandomUtil.uuId(), flowMsgModel, userInfo);
        WorkJobUtil.insertRedis(workJobModel, redisUtil);
        //超时
        for (FlowTaskOperatorEntity operatorOne : operatorListAll) {
            WorkTimeoutJobModel workTimeoutJobModel = WorkTimeoutJobModel.builder().flowModel(flowModel)
                    .taskId(flowTask.getId()).taskNodeId(operatorOne.getTaskNodeId()).taskNodeOperatorId(operatorOne.getId()).operatorEntity(operatorOne)
                    .tenantId(userInfo.getTenantId()).tenantDbConnectionString(userInfo.getTenantDbConnectionString()).build();
            workTimeoutJobUtil.insertRedis(workTimeoutJobModel, redisUtil);
        }
        //自动审批
        FlowApproveModel approveModel = FlowApproveModel.builder().operatorList(operatorListAll).taskNodeList(taskNodeList).flowTask(flowTask).flowModel(flowModel).build();
        flowTaskUtil.approve(approveModel);
        //查询代办用户是否通过
        flowTaskUtil.approverPass(flowTask, taskNodeList, flowModel, operator);
    }

    @Override
    public void reject(String id, FlowModel flowModel) throws WorkFlowException {
        FlowTaskOperatorEntity operator = flowTaskOperatorService.getInfo(id);
        if (operator != null) {
            if (FlowNature.ProcessCompletion.equals(operator.getCompletion())) {
                FlowTaskEntity flowTaskEntity = flowTaskService.getInfo(operator.getTaskId());
                this.reject(flowTaskEntity, operator, flowModel);
            }
        }
    }

    @Override
    @DSTransactional
    public void reject(FlowTaskEntity flowTask, FlowTaskOperatorEntity operator, FlowModel flowModel) throws WorkFlowException {
        UserInfo userInfo = flowModel.getUserInfo();
        String userId = StringUtil.isNotEmpty(flowModel.getUserId()) ? flowModel.getUserId() : userInfo.getUserId();
        //流程所有节点
        List<FlowTaskNodeEntity> flowTaskNodeAll = flowTaskNodeService.getList(flowTask.getId());
        List<FlowTaskNodeEntity> taskNodeList = flowTaskNodeAll.stream().filter(t -> FlowNodeEnum.Process.getCode().equals(t.getState())).collect(Collectors.toList());
        //当前节点
        Optional<FlowTaskNodeEntity> first = taskNodeList.stream().filter(m -> m.getId().equals(operator.getTaskNodeId())).findFirst();
        if (!first.isPresent()) {
            throw new WorkFlowException(MsgCode.COD001.get());
        }
        FlowTaskNodeEntity taskNode = first.get();
        FlowEngineEntity engine = flowEngineService.getInfo(flowTask.getFlowId());
        flowTaskUtil.candidateList(flowModel, taskNodeList, operator);
        //当前节点属性
        ChildNodeList nodeModel = JsonUtil.getJsonToBean(taskNode.getNodePropertyJson(), ChildNodeList.class);
        //驳回记录
        FlowTaskOperatorRecordEntity operatorRecord = new FlowTaskOperatorRecordEntity();
        //审批数据赋值
        FlowOperatordModel flowOperatordModel = FlowOperatordModel.builder().status(FlowRecordEnum.reject.getCode()).flowModel(flowModel).userId(userId).operator(operator).build();
        flowTaskUtil.operatorRecord(operatorRecord, flowOperatordModel);
        flowTaskOperatorRecordService.create(operatorRecord);
        //修改或签、会签经办数据
        TaskHandleIdStatus handleIdStatus = new TaskHandleIdStatus();
        handleIdStatus.setStatus(0);
        handleIdStatus.setNodeModel(nodeModel);
        handleIdStatus.setUserInfo(userInfo);
        handleIdStatus.setTaskNodeList(taskNodeList);
        flowTaskUtil.handleIdStatus(operator, handleIdStatus);
        //更新流当前程经办状态
        flowTaskOperatorService.update(operator);
        List<FlowTaskEntity> childList = flowTaskService.getChildList(operatorRecord.getTaskId(), FlowTaskEntity::getId);
        boolean isNext = childList.size() > 0;
        if (isNext) {
            throw new WorkFlowException(MsgCode.WF110.get());
        }
        boolean isReject = flowTaskUtil.isReject(taskNode);
        //更新驳回节点
        List<ChildNodeList> nextOperatorList = new LinkedList<>();
        Set<FlowTaskNodeEntity> thisStepAll = new HashSet<>();
        String[] thisStepId = flowTask.getThisStepId().split(",");
        List<FlowTaskNodeEntity> upAll = flowTaskUtil.isUpAll(taskNodeList, taskNode, isReject, thisStepAll, thisStepId);
        for (FlowTaskNodeEntity entity : upAll) {
            ChildNodeList node = JsonUtil.getJsonToBean(entity.getNodePropertyJson(), ChildNodeList.class);
            nextOperatorList.add(node);
        }
        //驳回节点
        List<FlowTaskOperatorEntity> operatorList = new LinkedList<>();
        //如果开始节点就不需要找下一节点
        boolean isStart = nextOperatorList.stream().filter(t -> FlowNature.NodeStart.equals(t.getCustom().getType())).count() > 0;
        if (!isStart) {
            //赋值数据
            flowModel.setProcessId(flowTask.getId());
            flowModel.setId(flowTask.getId());
            Map<String, Object> data = JsonUtil.stringToMap(flowTask.getFlowFormContentJson());
            flowModel.setFormData(data);
            FlowOperator flowOperator = FlowOperator.builder().operatorListAll(operatorList).flowModel(flowModel).flowTask(flowTask).nodeList(nextOperatorList).taskNodeListAll(taskNodeList).reject(true).asyncTaskList(new HashMap<>()).build();
            flowTaskUtil.nextOperator(flowOperator);
        }
        //更新驳回当前节点
        List<String> stepIdList = new LinkedList<>();
        List<String> stepNameList = new LinkedList<>();
        List<String> progressList = new LinkedList<>();
        List<String> rejectList = new LinkedList<>();
        for (FlowTaskNodeEntity taskNodes : thisStepAll) {
            boolean isUser = operatorList.stream().filter(t -> t.getTaskNodeId().equals(taskNodes.getId())).count() > 0;
            if (isUser) {
                ChildNodeList childNode = JsonUtil.getJsonToBean(taskNodes.getNodePropertyJson(), ChildNodeList.class);
                Properties properties = childNode.getProperties();
                String progress = properties.getProgress();
                if (StringUtil.isNotEmpty(progress)) {
                    progressList.add(progress);
                }
                stepIdList.add(taskNodes.getNodeCode());
                stepNameList.add(taskNodes.getNodeName());
                rejectList.add(taskNodes.getId());
            }
        }
        //驳回比例不够，不修改当前节点
        if (thisStepAll.size() > 0) {
            //驳回比例够又没有人,异常是默认通过,不修改当前节点
            if (operatorList.size() != 0) {
                Collections.sort(progressList);
                flowTask.setCompletion(progressList.size() > 0 ? Integer.parseInt(progressList.get(0)) : 0);
                flowTask.setThisStepId(String.join(",", stepIdList));
                flowTask.setThisStep(String.join(",", stepNameList));
                //判断驳回节点是否是开发节点
                flowTask.setStatus(isStart ? FlowTaskStatusEnum.Reject.getCode() : flowTask.getStatus());
                //会签拒绝更新未审批用户
                Set<String> rejectNodeList = new HashSet<>();
                flowTaskUtil.upAll(rejectNodeList, rejectList, taskNodeList);
                flowTaskOperatorService.updateReject(flowTask.getId(), rejectNodeList);
                flowOperatorUserService.updateReject(flowTask.getId(), rejectNodeList);
                //驳回节点之后的状态修改
                flowTaskNodeService.updateCompletion(new ArrayList<>(rejectNodeList), FlowNature.ProcessCompletion);
                flowTaskOperatorRecordService.updateStatus(rejectNodeList, flowTask.getId());
                //删除节点候选人
                List<String> candidates = new LinkedList<>();
                rejectNodeList.removeAll(rejectList);
                candidates.addAll(rejectNodeList);
                flowCandidatesService.deleteTaskNodeId(candidates);
                flowTaskNodeService.updateTaskNodeCandidates(candidates);
            }
        }
        if (isStart) {
            flowTask.setStatus(FlowTaskStatusEnum.Reject.getCode());
            flowTask.setCompletion(FlowNature.ProcessCompletion);
            flowTask.setThisStepId(String.join(",", new ArrayList<>()));
            flowTask.setThisStep(String.join(",", new ArrayList<>()));
//            UserEntity user = serviceUtil.getUserInfo(flowTask.getCreatorUserId());
//            flowTask.setFullName(user != null ? user.getRealName() + "的" + flowTask.getFlowName() : "的" + flowTask.getFlowName());
            flowTaskNodeService.update(flowTask.getId());
            flowTaskOperatorService.update(flowTask.getId());
            flowTaskOperatorRecordService.update(flowTask.getId());
            flowUserService.deleteByTaskId(flowTask.getId());
            flowOperatorUserService.deleteByTaskId(flowTask.getId());
        }
        //更新流程节点
        flowTask.setTaskNodeId(null);
        flowTaskService.update(flowTask);
        //显示当前的驳回记录
        flowTaskOperatorRecordService.update(operatorRecord.getId(), operatorRecord);
        //创建审批人
        Map<String, List<FlowTaskOperatorEntity>> operatorMap = operatorList.stream().collect(Collectors.groupingBy(FlowTaskOperatorEntity::getTaskNodeId));
        for (ChildNodeList childNodeList : nextOperatorList) {
            Properties properties = childNodeList.getProperties();
            boolean counterSign = FlowNature.ImproperApprover.equals(properties.getCounterSign());
            if (counterSign && StringUtil.isEmpty(flowModel.getFreeApproverUserId())) {
                List<FlowTaskOperatorEntity> listAll = operatorMap.get(childNodeList.getTaskNodeId()) != null ? operatorMap.get(childNodeList.getTaskNodeId()) : new LinkedList<>();
                flowOperatorUserService.create(JsonUtil.getJsonToList(listAll, FlowOperatorUserEntity.class));
            }
        }
        //过滤依次审批人
        flowTaskUtil.improperApproverUser(operatorList, taskNodeList, nodeModel, operator);
        flowTaskOperatorService.create(operatorList);
        //更新节点接收时间
        flowTaskUtil.taskCreatTime(operatorList);
        //获取抄送人
        List<FlowTaskCirculateEntity> circulateList = new LinkedList<>();
        flowTaskUtil.circulateList(nodeModel, circulateList, flowModel);
        flowTaskCirculateService.create(circulateList);
        //节点事件
        flowMsgUtil.event(5, nodeModel, operatorRecord, flowModel);
        //发送消息
        FlowMsgModel flowMsgModel = new FlowMsgModel();
        flowMsgModel.setCirculateList(circulateList);
        flowMsgModel.setNodeList(taskNodeList);
        List<FlowTaskOperatorEntity> operatorListAll = new ArrayList() {{
            addAll(operatorList);
        }};
        flowMsgModel.setOperatorList(operatorListAll);
        flowMsgModel.setReject(true);
        flowMsgModel.setCopy(true);
        flowMsgModel.setStart(isStart);
        flowMsgModel.setData(JsonUtil.stringToMap(flowTask.getFlowFormContentJson()));
        flowMsgModel.setTaskNodeEntity(taskNode);
        flowMsgModel.setTaskEntity(flowTask);
        flowMsgModel.setEngine(engine);
        FlowTaskOperatorRecordEntity taskOperatorRecord = new FlowTaskOperatorRecordEntity();
        taskOperatorRecord.setHandleId(userInfo.getUserId());
        flowMsgModel.setFlowModel(flowModel);
//        flowMsgUtil.message(flowMsgModel);
        //定时器
        WorkJobModel workJobModel = new WorkJobModel(operator.getId(), flowMsgModel, userInfo);
        WorkJobUtil.insertRedis(workJobModel, redisUtil);
        //超时
        for (FlowTaskOperatorEntity operatorOne : operatorListAll) {
            WorkTimeoutJobModel workTimeoutJobModel = WorkTimeoutJobModel.builder().flowModel(flowModel)
                    .taskId(flowTask.getId()).taskNodeId(operatorOne.getTaskNodeId()).taskNodeOperatorId(operatorOne.getId()).operatorEntity(operatorOne)
                    .tenantId(userInfo.getTenantId()).tenantDbConnectionString(userInfo.getTenantDbConnectionString()).build();
            workTimeoutJobUtil.insertRedis(workTimeoutJobModel, redisUtil);
        }
        //自动审批
        FlowApproveModel approveModel = FlowApproveModel.builder().operatorList(operatorListAll).taskNodeList(taskNodeList).flowTask(flowTask).flowModel(flowModel).build();
        flowTaskUtil.approve(approveModel);
    }

    @Override
    @DSTransactional
    public void recall(String id, FlowTaskOperatorRecordEntity operatorRecord, FlowModel flowModel) throws WorkFlowException {
        UserInfo userInfo = flowModel.getUserInfo();
        //撤回经办
        FlowTaskOperatorEntity operatorEntity = flowTaskOperatorService.getInfo(operatorRecord.getTaskOperatorId());
        if (FlowNodeEnum.Futility.getCode().equals(operatorEntity.getState())) {
            throw new WorkFlowException(MsgCode.WF104.get());
        }
        //撤回节点
        FlowTaskNodeEntity flowTaskNodeEntity = flowTaskNodeService.getInfo(operatorRecord.getTaskNodeId());
        //撤回任务
        FlowTaskEntity flowTask = flowTaskService.getInfo(operatorRecord.getTaskId());
        //所有节点
        List<FlowTaskNodeEntity> flowTaskNodeEntityList = flowTaskNodeService.getList(operatorRecord.getTaskId()).stream().filter(t -> FlowNodeEnum.Process.getCode().equals(t.getState())).collect(Collectors.toList());
        //所有经办
        List<FlowTaskOperatorEntity> flowTaskOperatorEntityList = flowTaskOperatorService.getList(operatorRecord.getTaskId()).stream().filter(t -> FlowNodeEnum.Process.getCode().equals(t.getState())).collect(Collectors.toList());
        //撤回节点属性
        ChildNodeList nodeModel = JsonUtil.getJsonToBean(flowTaskNodeEntity.getNodePropertyJson(), ChildNodeList.class);
        //拒绝不撤回
        if (FlowNature.ProcessCompletion.equals(operatorEntity.getHandleStatus())) {
            throw new WorkFlowException(MsgCode.WF104.get());
        }
        //任务待审状态才能撤回
        if (!(flowTask.getEnabledMark() == 1 && FlowTaskStatusEnum.Handle.getCode().equals(flowTask.getStatus()))) {
            throw new WorkFlowException(MsgCode.WF105.get());
        }
        //撤回节点下一节点已操作
        List<FlowTaskOperatorEntity> recallNextOperatorList = flowTaskOperatorEntityList.stream().filter(x -> flowTaskNodeEntity.getNodeNext().contains(x.getNodeCode())).collect(Collectors.toList());
        boolean isRecall = recallNextOperatorList.stream().filter(t -> FlowNature.AuditCompletion.equals(t.getCompletion()) && FlowNodeEnum.Process.getCode().equals(t.getState())).count() > 0;
        if (isRecall) {
            throw new WorkFlowException(MsgCode.WF106.get());
        }
        List<FlowTaskEntity> childList = flowTaskService.getChildList(operatorRecord.getTaskId(), FlowTaskEntity::getId);
        boolean isNext = childList.size() > 0;
        if (isNext) {
            throw new WorkFlowException(MsgCode.WF107.get());
        }
        //加签人
        Set<FlowTaskOperatorEntity> operatorList = new HashSet<>();
        flowTaskUtil.getOperator(operatorEntity.getId(), operatorList);
        operatorEntity.setHandleStatus(null);
        operatorEntity.setHandleTime(null);
        operatorEntity.setCreatorTime(new Date());
        operatorEntity.setCompletion(FlowNature.ProcessCompletion);
        operatorEntity.setState(FlowNodeEnum.Process.getCode());
        operatorList.add(operatorEntity);
        List<String> delOperatorRecordIds = new LinkedList<>();
        for (FlowTaskOperatorEntity item : operatorList) {
            FlowTaskOperatorRecordEntity record = flowTaskOperatorRecordService.getInfo(item.getTaskId(), item.getTaskNodeId(), item.getId());
            if (record != null) {
                delOperatorRecordIds.add(record.getId());
            }
        }
        Set<String> rejectNodeList = new HashSet<>();
        List<String> rejectList = new ArrayList() {{
            add(flowTaskNodeEntity.getId());
        }};
        flowTaskUtil.upAll(rejectNodeList, rejectList, flowTaskNodeEntityList);
        //撤回节点是否完成
        if (FlowNature.AuditCompletion.equals(flowTaskNodeEntity.getCompletion())) {
            //撤回节点下一节点经办删除
            List<String> idAll = recallNextOperatorList.stream().map(FlowTaskOperatorEntity::getId).collect(Collectors.toList());
            flowTaskOperatorService.updateTaskOperatorState(idAll);
            List<FlowTaskOperatorEntity> hanleOperatorList = flowTaskOperatorEntityList.stream().filter(x -> x.getTaskNodeId().equals(operatorRecord.getTaskNodeId()) && Objects.isNull(x.getHandleStatus()) && Objects.isNull(x.getHandleTime()) && Objects.isNull(x.getParentId())).collect(Collectors.toList());
            for (FlowTaskOperatorEntity taskOperator : hanleOperatorList) {
                taskOperator.setCompletion(FlowNature.ProcessCompletion);
            }
            operatorList.addAll(hanleOperatorList);
            flowTaskNodeService.updateCompletion(new ArrayList<>(rejectNodeList), FlowNature.ProcessCompletion);
            //更新任务流程
            List<String> stepIdList = new ArrayList<>(Arrays.asList(flowTask.getThisStepId().split(",")));
            List<String> stepNameList = new LinkedList<>();
            List<String> progressList = new LinkedList<>();
            List<String> rejectNodeCode = flowTaskNodeEntityList.stream().filter(t -> rejectNodeList.contains(t.getId())).map(FlowTaskNodeEntity::getNodeCode).collect(Collectors.toList());
            stepIdList.removeAll(rejectNodeCode);
            stepIdList.add(flowTaskNodeEntity.getNodeCode());
            List<FlowTaskNodeEntity> recallNodeList = flowTaskNodeEntityList.stream().filter(x -> stepIdList.contains(x.getNodeCode())).collect(Collectors.toList());
            for (FlowTaskNodeEntity taskNodeEntity : recallNodeList) {
                ChildNodeList childNode = JsonUtil.getJsonToBean(taskNodeEntity.getNodePropertyJson(), ChildNodeList.class);
                Properties properties = childNode.getProperties();
                String progress = properties.getProgress();
                if (StringUtil.isNotEmpty(progress)) {
                    progressList.add(progress);
                }
                stepIdList.add(taskNodeEntity.getNodeCode());
                stepNameList.add(taskNodeEntity.getNodeName());
            }
            //更新当前节点
            flowTask.setCompletion(progressList.size() > 0 ? Integer.parseInt(progressList.get(0)) : 0);
            flowTask.setThisStepId(String.join(",", stepIdList));
            flowTask.setThisStep(String.join(",", stepNameList));
            flowTask.setStatus(FlowTaskStatusEnum.Handle.getCode());
            flowTaskService.update(flowTask);
        }
        for (FlowTaskOperatorEntity taskOperator : operatorList) {
            flowTaskOperatorService.update(taskOperator);
        }
        if (FlowNature.ParentId.equals(operatorEntity.getParentId())) {
            FlowTaskNodeEntity node = flowTaskNodeService.getInfo(operatorEntity.getTaskNodeId());
            List<String> nextNode = Arrays.asList(node.getNodeNext().split(","));
            List<FlowTaskNodeEntity> list = flowTaskNodeService.getList(operatorEntity.getTaskId()).stream().filter(t -> nextNode.contains(t.getNodeCode()) && FlowNodeEnum.Process.getCode().equals(t.getState())).collect(Collectors.toList());
            int num = 0;
            for (FlowTaskNodeEntity taskNode : list) {
                List<String> candidateList = StringUtil.isNotEmpty(taskNode.getCandidates()) ? JsonUtil.getJsonToList(taskNode.getCandidates(), String.class) : new ArrayList<>();
                num += candidateList.size() > 0 ? 1 : 0;
            }
            if (num > 0) {
                //删除异常人
                List<String> candidateList = list.stream().map(FlowTaskNodeEntity::getId).collect(Collectors.toList());
                flowCandidatesService.deleteTaskNodeId(candidateList, FlowNature.Candidates);
            }
            rejectNodeList.removeAll(rejectList);
            flowTaskNodeService.updateTaskNodeCandidates(new ArrayList<>(rejectNodeList));
            //删除异常人
            flowCandidatesService.deleteTaskNodeId(new ArrayList<>(rejectNodeList), FlowNature.CandidatesError);
            //删除依次审批人
            FlowOperatorUserEntity nextOperatorUser = flowOperatorUserService.getList(flowTask.getId()).stream().filter(t -> operatorEntity.getSortCode().equals(t.getSortCode() - 1)).findFirst().orElse(null);
            if (nextOperatorUser != null) {
                boolean count = flowTaskOperatorEntityList.stream().filter(t -> t.getId().equals(nextOperatorUser.getId()) && FlowNature.AuditCompletion.equals(t.getCompletion())).count() > 0;
                if (count) {
                    throw new WorkFlowException(MsgCode.WF104.get());
                } else {
                    flowTaskOperatorService.deleteList(new ArrayList() {{
                        add(nextOperatorUser.getId());
                    }});
                }
            }
        }
        List<String> taskOperatorId = operatorList.stream().map(t -> t.getId()).collect(Collectors.toList());
        flowCandidatesService.delete(taskOperatorId);
        //删除经办记录
        delOperatorRecordIds.add(operatorRecord.getId());
        flowTaskOperatorRecordService.updateStatus(delOperatorRecordIds);
        //撤回记录
        FlowTaskOperatorEntity operator = JsonUtil.getJsonToBean(operatorRecord, FlowTaskOperatorEntity.class);
        operator.setId(operatorRecord.getTaskOperatorId());
        //审批数据赋值
        FlowOperatordModel flowOperatordModel = FlowOperatordModel.builder().status(FlowRecordEnum.revoke.getCode()).flowModel(flowModel).userId(userInfo.getUserId()).operator(operator).build();
        flowTaskUtil.operatorRecord(operatorRecord, flowOperatordModel);
        flowTaskOperatorRecordService.create(operatorRecord);
        flowModel.setFormData(JsonUtil.stringToMap(flowTask.getFlowFormContentJson()));
        //节点事件
        flowMsgUtil.event(6, nodeModel, operatorRecord, flowModel);
        //超时
        for (FlowTaskOperatorEntity operatorOne : operatorList) {
            WorkTimeoutJobModel workTimeoutJobModel = WorkTimeoutJobModel.builder().flowModel(flowModel)
                    .taskId(flowTask.getId()).taskNodeId(operatorOne.getTaskNodeId()).taskNodeOperatorId(operatorOne.getId()).operatorEntity(operatorOne)
                    .tenantId(userInfo.getTenantId()).tenantDbConnectionString(userInfo.getTenantDbConnectionString()).build();
            workTimeoutJobUtil.insertRedis(workTimeoutJobModel, redisUtil);
        }
    }

    @Override
    @DSTransactional
    public void revoke(FlowTaskEntity flowTask, FlowModel flowModel) throws WorkFlowException {
        UserInfo userInfo = flowModel.getUserInfo();
        List<FlowTaskNodeEntity> list = flowTaskNodeService.getList(flowTask.getId());
        FlowTaskNodeEntity start = list.stream().filter(t -> FlowNature.NodeStart.equals(String.valueOf(t.getNodeType()))).findFirst().orElse(null);
        //删除节点
        flowTaskNodeService.deleteByTaskId(flowTask.getId());
        //删除经办
        flowTaskOperatorService.deleteByTaskId(flowTask.getId());
        //删除候选人
        flowCandidatesService.deleteByTaskId(flowTask.getId());
        //删除发起用户信息
        flowUserService.deleteByTaskId(flowTask.getId());
        //修改经办记录状态
//        List<String> recordListAll = flowTaskOperatorRecordService.getList(flowTask.getId()).stream().map(FlowTaskOperatorRecordEntity::getId).collect(Collectors.toList());
//        flowTaskOperatorRecordService.updateStatus(recordListAll);
        //更新当前节点
        flowTask.setThisStep("开始");
        flowTask.setCompletion(FlowNature.ProcessCompletion);
        flowTask.setStatus(FlowTaskStatusEnum.Revoke.getCode());
        flowTask.setStartTime(null);
        flowTask.setEndTime(null);
//        UserEntity user = serviceUtil.getUserInfo(flowTask.getCreatorUserId());
//        flowTask.setFullName(user != null ? user.getRealName() + "的" + flowTask.getFlowName() : "的" + flowTask.getFlowName());
        flowTaskService.update(flowTask);
        //撤回记录
        FlowTaskOperatorRecordEntity operatorRecord = new FlowTaskOperatorRecordEntity();
        operatorRecord.setTaskId(flowTask.getId());
        operatorRecord.setHandleStatus(FlowRecordEnum.revoke.getCode());
        FlowTaskOperatorEntity operator = JsonUtil.getJsonToBean(operatorRecord, FlowTaskOperatorEntity.class);
        //审批数据赋值
        FlowOperatordModel flowOperatordModel = FlowOperatordModel.builder().status(FlowRecordEnum.revoke.getCode()).flowModel(flowModel).userId(userInfo.getUserId()).operator(operator).build();
        flowTaskUtil.operatorRecord(operatorRecord, flowOperatordModel);
        flowTaskOperatorRecordService.create(operatorRecord);
        //撤回事件
        if (start != null) {
            ChildNodeList nodeModel = JsonUtil.getJsonToBean(start.getNodePropertyJson(), ChildNodeList.class);
            flowModel.setFormData(JsonUtil.stringToMap(flowTask.getFlowFormContentJson()));
            operatorRecord.setHandleStatus(FlowTaskStatusEnum.Revoke.getCode());
            flowMsgUtil.event(3, nodeModel, operatorRecord, flowModel);
        }
        List<String> childAllList = flowTaskService.getChildAllList(flowTask.getId());
        childAllList.remove(flowTask.getId());
        List<FlowTaskEntity> orderStaList = flowTaskService.getOrderStaList(childAllList);
        for (FlowTaskEntity flowTaskEntity : orderStaList) {
            FlowModel cancelModel = new FlowModel();
            cancelModel.setUserInfo(flowModel.getUserInfo());
            this.revoke(flowTaskEntity, flowModel);
        }
    }

    @Override
    @DSTransactional
    public void cancel(FlowTaskEntity flowTask, FlowModel flowModel) throws WorkFlowException {
        UserInfo userInfo = flowModel.getUserInfo();
        //终止记录
        FlowTaskOperatorRecordEntity operatorRecord = new FlowTaskOperatorRecordEntity();
        FlowTaskOperatorEntity operator = new FlowTaskOperatorEntity();
        operator.setTaskId(flowTask.getId());
        operator.setNodeCode(flowTask.getThisStepId());
        operator.setNodeName(flowTask.getThisStep());
        //审批数据赋值
        FlowOperatordModel flowOperatordModel = FlowOperatordModel.builder().status(FlowRecordEnum.cancel.getCode()).flowModel(flowModel).userId(userInfo.getUserId()).operator(operator).build();
        flowTaskUtil.operatorRecord(operatorRecord, flowOperatordModel);
        flowTaskOperatorRecordService.create(operatorRecord);
        //更新实例
        flowTask.setStatus(FlowTaskStatusEnum.Cancel.getCode());
        flowTask.setEndTime(new Date());
        flowTaskService.update(flowTask);
        //发送消息
        FlowEngineEntity engine = flowEngineService.getInfo(flowTask.getFlowId());
        List<FlowTaskNodeEntity> taskNodeList = flowTaskNodeService.getList(flowTask.getId()).stream().filter(t -> FlowNodeEnum.Process.getCode().equals(t.getState())).collect(Collectors.toList());
        String nodeJson = "{}";
        FlowTaskNodeEntity start = taskNodeList.stream().filter(t -> FlowNature.NodeStart.equals(t.getNodeType())).findFirst().orElse(null);
        if (start != null) {
            nodeJson = start.getNodePropertyJson();
        }
        FlowMsgModel flowMsgModel = new FlowMsgModel();
        flowMsgModel.setEnd(true);
        flowMsgModel.setCirculateList(new ArrayList<>());
        flowMsgModel.setNodeList(taskNodeList);
        flowMsgModel.setOperatorList(new ArrayList<>());
        flowMsgModel.setTaskEntity(flowTask);
        FlowTaskNodeEntity taskNodeEntity = new FlowTaskNodeEntity();
        taskNodeEntity.setNodePropertyJson(nodeJson);
        flowMsgModel.setTaskNodeEntity(taskNodeEntity);
        flowMsgModel.setEngine(engine);
        flowMsgModel.setData(JsonUtil.stringToMap(flowTask.getFlowFormContentJson()));
        flowMsgModel.setFlowModel(flowModel);
        flowMsgUtil.message(flowMsgModel);
        //递归查询子流程，并终止
        List<String> childAllList = flowTaskService.getChildAllList(flowTask.getId());
        childAllList.remove(flowTask.getId());
        List<FlowTaskEntity> orderStaList = flowTaskService.getOrderStaList(childAllList);
        for (FlowTaskEntity flowTaskEntity : orderStaList) {
            FlowModel cancelModel = new FlowModel();
            cancelModel.setUserInfo(flowModel.getUserInfo());
            this.cancel(flowTaskEntity, flowModel);
        }
    }

    @Override
    @DSTransactional
    public void assign(String id, FlowModel flowModel) throws WorkFlowException {
        List<FlowTaskOperatorEntity> list = flowTaskOperatorService.getList(id).stream().filter(t -> FlowNodeEnum.Process.getCode().equals(t.getState()) && flowModel.getNodeCode().equals(t.getNodeCode())).collect(Collectors.toList());
        List<FlowTaskNodeEntity> taskNodeList = flowTaskNodeService.getList(id);
        FlowTaskNodeEntity taskNode = taskNodeList.stream().filter(t -> flowModel.getNodeCode().equals(t.getNodeCode())).findFirst().orElse(null);
        ChildNodeList childNode = JsonUtil.getJsonToBean(taskNode.getNodePropertyJson(), ChildNodeList.class);
        List<FlowTaskOperatorEntity> operatorList = new LinkedList<>();
        TaskOperatoUser taskOperatoUser = new TaskOperatoUser();
        taskOperatoUser.setDate(new Date());
        taskOperatoUser.setChildNode(childNode);
        taskOperatoUser.setAutomation("");
        taskOperatoUser.setId(FlowNature.ParentId);
        taskOperatoUser.setHandLeId(flowModel.getFreeApproverUserId());
        taskOperatoUser.setSortCode(1);
        flowTaskUtil.operatorUser(operatorList, taskOperatoUser);
        List<String> idAll = list.stream().map(FlowTaskOperatorEntity::getId).collect(Collectors.toList());
        flowTaskOperatorService.deleteList(idAll);
        flowTaskOperatorService.create(operatorList);
        Set<String> taskNodeId = new HashSet() {{
            add(taskNode.getId());
        }};
        flowOperatorUserService.updateReject(id, taskNodeId);
        //指派记录
        UserInfo userInfo = flowModel.getUserInfo();
        FlowTaskOperatorRecordEntity operatorRecord = new FlowTaskOperatorRecordEntity();
        FlowTaskOperatorEntity operator = new FlowTaskOperatorEntity();
        operator.setTaskId(taskNode.getTaskId());
        operator.setNodeCode(taskNode.getNodeCode());
        operator.setNodeName(taskNode.getNodeName());
        //审批数据赋值
        FlowOperatordModel flowOperatordModel = FlowOperatordModel.builder().status(FlowRecordEnum.assign.getCode()).flowModel(flowModel).userId(userInfo.getUserId()).operator(operator).operatorId(flowModel.getFreeApproverUserId()).build();
        flowTaskUtil.operatorRecord(operatorRecord, flowOperatordModel);
        flowTaskOperatorRecordService.create(operatorRecord);
        //发送消息
        FlowTaskEntity flowTask = flowTaskService.getInfoSubmit(id);
        FlowEngineEntity engine = flowEngineService.getInfo(flowTask.getFlowId());
        FlowMsgModel flowMsgModel = new FlowMsgModel();
        flowMsgModel.setCirculateList(new ArrayList<>());
        flowMsgModel.setTitle("已被【指派】");
        flowMsgModel.setData(JsonUtil.stringToMap(flowTask.getFlowFormContentJson()));
        flowMsgModel.setNodeList(taskNodeList);
        flowMsgModel.setOperatorList(operatorList);
        flowMsgModel.setTaskNodeEntity(taskNode);
        flowMsgModel.setTaskEntity(flowTask);
        flowMsgModel.setEngine(engine);
        flowMsgModel.setFlowModel(flowModel);
        flowMsgUtil.message(flowMsgModel);
        //超时
        for (FlowTaskOperatorEntity operatorOne : operatorList) {
            WorkTimeoutJobModel workTimeoutJobModel = WorkTimeoutJobModel.builder().flowModel(flowModel)
                    .taskId(flowTask.getId()).taskNodeId(operatorOne.getTaskNodeId()).taskNodeOperatorId(operatorOne.getId()).operatorEntity(operatorOne)
                    .tenantId(userInfo.getTenantId()).tenantDbConnectionString(userInfo.getTenantDbConnectionString()).build();
            workTimeoutJobUtil.insertRedis(workTimeoutJobModel, redisUtil);
        }
    }

    @Override
    @DSTransactional
    public void transfer(FlowTaskOperatorEntity taskOperator, FlowModel flowModel) throws WorkFlowException {
        flowTaskOperatorService.update(taskOperator);
        List<FlowTaskNodeEntity> taskNodeList = flowTaskNodeService.getList(taskOperator.getTaskId());
        FlowTaskNodeEntity taskNode = taskNodeList.stream().filter(t -> t.getId().equals(taskOperator.getTaskNodeId())).findFirst().orElse(null);
        ChildNodeList childNode = JsonUtil.getJsonToBean(taskNode.getNodePropertyJson(), ChildNodeList.class);
        FlowTaskEntity flowTask = flowTaskService.getInfoSubmit(taskNode.getTaskId(), FlowTaskEntity::getId, FlowTaskEntity::getFlowId, FlowTaskEntity::getFullName, FlowTaskEntity::getCreatorUserId, FlowTaskEntity::getStatus, FlowTaskEntity::getFlowFormContentJson);
        //转办记录
        UserInfo userInfo = flowModel.getUserInfo();
        FlowTaskOperatorRecordEntity operatorRecord = new FlowTaskOperatorRecordEntity();
        FlowTaskOperatorEntity operator = new FlowTaskOperatorEntity();
        operator.setTaskId(taskOperator.getTaskId());
        operator.setNodeCode(taskOperator.getNodeCode());
        operator.setTaskNodeId(taskOperator.getTaskNodeId());
        operator.setNodeName(taskOperator.getNodeName());
        //审批数据赋值
        FlowOperatordModel flowOperatordModel = FlowOperatordModel.builder().status(FlowRecordEnum.transfer.getCode()).flowModel(flowModel).userId(userInfo.getUserId()).operator(operator).operatorId(taskOperator.getHandleId()).build();
        flowTaskUtil.operatorRecord(operatorRecord, flowOperatordModel);
        flowTaskOperatorRecordService.create(operatorRecord);
        //自动审批
        List<FlowTaskOperatorEntity> operatorListAll = new LinkedList<>();
        List<UserEntity> userName = new ArrayList() {{
            UserEntity user = new UserEntity();
            user.setId(taskOperator.getHandleId());
            add(user);
        }};
        TaskOperatoUser taskOperatoUser = new TaskOperatoUser();
        taskOperatoUser.setDate(new Date());
        taskOperatoUser.setId(FlowNature.ParentId);
        taskOperatoUser.setHandLeId(operator.getHandleId());
        taskOperatoUser.setChildNode(childNode);
        FlowAgreeRuleModel ruleModel = FlowAgreeRuleModel.builder().operatorListAll(operatorListAll).taskOperatoUser(taskOperatoUser).flowTask(flowTask).userName(userName).childNode(childNode).taskNodeList(taskNodeList).reject(false).build();
        flowTaskUtil.flowAgreeRule(ruleModel);
        operatorListAll.stream().forEach(t -> t.setId(taskOperator.getId()));
        //发送消息
        FlowEngineEntity engine = flowEngineService.getInfo(flowTask.getFlowId());
        List<FlowTaskOperatorEntity> operatorList = new ArrayList() {{
            FlowTaskOperatorEntity operatorEntity = new FlowTaskOperatorEntity();
            operatorEntity.setId(taskOperator.getId());
            operatorEntity.setTaskId(operatorRecord.getTaskId());
            operatorEntity.setHandleId(taskOperator.getHandleId());
            operatorEntity.setTaskNodeId(operatorRecord.getTaskNodeId());
            add(operatorEntity);
        }};
        FlowMsgModel flowMsgModel = new FlowMsgModel();
        flowMsgModel.setCirculateList(new ArrayList<>());
        flowMsgModel.setTitle("已被【转办】");
        flowMsgModel.setNodeList(taskNodeList);
        flowMsgModel.setOperatorList(operatorList);
        flowMsgModel.setData(JsonUtil.stringToMap(flowTask.getFlowFormContentJson()));
        flowMsgModel.setTaskNodeEntity(taskNode);
        flowMsgModel.setTaskEntity(flowTask);
        flowMsgModel.setEngine(engine);
        flowMsgModel.setFlowModel(flowModel);
        flowMsgUtil.message(flowMsgModel);
        //自动审批
        FlowApproveModel approveModel = FlowApproveModel.builder().operatorList(operatorListAll).taskNodeList(taskNodeList).flowTask(flowTask).flowModel(flowModel).build();
        flowTaskUtil.approve(approveModel);
        //超时
        for (FlowTaskOperatorEntity operatorOne : operatorListAll) {
            WorkTimeoutJobModel workTimeoutJobModel = WorkTimeoutJobModel.builder().flowModel(flowModel)
                    .taskId(flowTask.getId()).taskNodeId(operatorOne.getTaskNodeId()).taskNodeOperatorId(operatorOne.getId()).operatorEntity(operatorOne)
                    .tenantId(userInfo.getTenantId()).tenantDbConnectionString(userInfo.getTenantDbConnectionString()).build();
            workTimeoutJobUtil.insertRedis(workTimeoutJobModel, redisUtil);
        }
    }

    @Override
    public FlowBeforeInfoVO getBeforeInfo(String id, String taskNodeId, String taskOperatorId) throws WorkFlowException {
        FlowBeforeInfoVO vo = new FlowBeforeInfoVO();
        FlowTaskEntity taskEntity = flowTaskService.getInfo(id);
        List<FlowTaskNodeEntity> taskNodeAllList = flowTaskNodeService.getList(taskEntity.getId()).stream().filter(t -> FlowNodeEnum.Process.getCode().equals(t.getState())).collect(Collectors.toList());
        //排除分支没有走过的节点
        flowTaskUtil.nodeList(taskNodeAllList);
        List<FlowTaskNodeEntity> taskNodeList = taskNodeAllList.stream().sorted(Comparator.comparing(FlowTaskNodeEntity::getSortCode)).collect(Collectors.toList());
        List<FlowTaskOperatorEntity> taskOperatorList = flowTaskOperatorService.getList(taskEntity.getId()).stream().filter(t -> FlowNodeEnum.Process.getCode().equals(t.getState()) && FlowNature.ParentId.equals(t.getParentId())).collect(Collectors.toList());
        Map<String, List<FlowTaskOperatorEntity>> nodeIdList = taskOperatorList.stream().filter(t -> FlowNature.ParentId.equals(t.getParentId())).collect(Collectors.groupingBy(FlowTaskOperatorEntity::getTaskNodeId));
        List<FlowTaskOperatorRecordEntity> operatorRecordList = flowTaskOperatorRecordService.getList(taskEntity.getId());
        List<FlowOperatorUserEntity> operatorUserAll = flowOperatorUserService.getList(taskEntity.getId());
        for (int i = 0; i < operatorUserAll.size(); i++) {
            FlowOperatorUserEntity operatorUserEntity = operatorUserAll.get(i);
            boolean count = taskOperatorList.stream().filter(t -> t.getId().equals(operatorUserEntity.getId())).count() > 0;
            if (count) {
                operatorUserAll.remove(i);
            }
        }
        Map<String, List<FlowOperatorUserEntity>> operatorNodeIdList = operatorUserAll.stream().collect(Collectors.groupingBy(FlowOperatorUserEntity::getTaskNodeId));
        boolean colorFlag = true;
        //流程任务
        FlowTaskModel inof = JsonUtil.getJsonToBean(taskEntity, FlowTaskModel.class);
        FlowEngineEntity engine = flowEngineService.getInfo(taskEntity.getFlowId());
        inof.setAppFormUrl(engine.getAppFormUrl());
        inof.setFormUrl(engine.getFormUrl());
        inof.setType(engine.getType());
        vo.setFlowTaskInfo(inof);
        //已办人员
        List<FlowTaskOperatorRecordModel> recordList = new LinkedList<>();
        List<String> userIdAll = new LinkedList<>();
        operatorRecordList.stream().forEach(t -> {
            userIdAll.add(t.getHandleId());
            if (StringUtil.isNotEmpty(t.getOperatorId())) {
                userIdAll.add(t.getOperatorId());
            }
        });
        userIdAll.addAll(taskOperatorList.stream().map(FlowTaskOperatorEntity::getHandleId).collect(Collectors.toList()));
        userIdAll.addAll(operatorUserAll.stream().map(FlowOperatorUserEntity::getHandleId).collect(Collectors.toList()));
        userIdAll.add(taskEntity.getCreatorUserId());
        //子流程人员
        List<FlowTaskEntity> childList = flowTaskService.getChildList(taskEntity.getId(), FlowTaskEntity::getId, FlowTaskEntity::getCreatorUserId);
        userIdAll.addAll(childList.stream().map(FlowTaskEntity::getCreatorUserId).collect(Collectors.toList()));
        List<UserEntity> userList = serviceUtil.getUserName(userIdAll);
        for (FlowTaskOperatorRecordEntity entity : operatorRecordList) {
            FlowTaskOperatorRecordModel infoModel = JsonUtil.getJsonToBean(entity, FlowTaskOperatorRecordModel.class);
            UserEntity operatorName = userList.stream().filter(t -> t.getId().equals(entity.getOperatorId())).findFirst().orElse(null);
            infoModel.setOperatorId(operatorName != null ? operatorName.getRealName() + "/" + operatorName.getAccount() : "");
            UserEntity userName = userList.stream().filter(t -> t.getId().equals(entity.getHandleId())).findFirst().orElse(null);
            infoModel.setUserName(userName != null ? userName.getRealName() + "/" + userName.getAccount() : "");
            FlowTaskOperatorEntity operatorEntity = taskOperatorList.stream().filter(t -> t.getId().equals(entity.getTaskOperatorId())).findFirst().orElse(null);
            int status = 0;
            if (operatorEntity != null) {
                status += FlowNature.ParentId.equals(operatorEntity.getParentId()) ? 0 : 1;
            }
            infoModel.setStatus(status);
            recordList.add(infoModel);
        }
        vo.setFlowTaskOperatorRecordList(recordList);
        //流程节点
        String[] tepId = taskEntity.getThisStepId() != null ? taskEntity.getThisStepId().split(",") : new String[]{};
        List<String> tepIdAll = Arrays.asList(tepId);
        List<FlowTaskNodeModel> flowTaskNodeListAll = JsonUtil.getJsonToList(taskNodeList, FlowTaskNodeModel.class);
        Long version = 0L;
        String versionKey = "f_version";
        Map<String, Object> objectMap = JsonUtil.stringToMap(taskEntity.getFlowFormContentJson());
        for (String key : objectMap.keySet()) {
            List<String> versionList = new ArrayList() {{
                add("version");
                add("f_version");
            }};
            if (versionList.contains(key.toLowerCase())) {
                Long versions = objectMap.get(key) != null ? Long.parseLong(String.valueOf(objectMap.get(key))) : 0L;
                version = versions > version ? versions : version;
                versionKey = versions > version ? versionKey : key;
            }
        }
        for (FlowTaskNodeModel model : flowTaskNodeListAll) {
            List<String> nodeId = new LinkedList<>();
            if (tepIdAll.contains(model.getNodeCode())) {
                model.setType("1");
                colorFlag = false;
                if (FlowNature.NodeEnd.equals(model.getNodeCode())) {
                    model.setType("0");
                }
            }
            //流程图节点颜色
            if (colorFlag || model.getCompletion() == 1) {
                if (model.getSortCode() != -2) {
                    model.setType("0");
                }
            }
            if (StringUtil.isNotEmpty(model.getType())) {
                nodeId.add(model.getType());
            }
            //查询审批人
            ChildNodeList childNode = JsonUtil.getJsonToBean(model.getNodePropertyJson(), ChildNodeList.class);
            Custom custom = childNode.getCustom();
            Properties properties = childNode.getProperties();
            String type = properties.getAssigneeType();
            List<FlowTaskOperatorEntity> operatorList = new LinkedList<>();
            FlowModel flowModel = new FlowModel();
            TaskOperator taskOperator = new TaskOperator();
            taskOperator.setChildNode(childNode);
            taskOperator.setTaskEntity(taskEntity);
            taskOperator.setFlowModel(flowModel);
            taskOperator.setDetails(false);
            taskOperator.setVerify(false);
            taskOperator.setTaskNodeList(taskNodeList);
            taskOperator.setId(FlowNature.ParentId);
            taskOperator.setUserInfo(new UserInfo());
            List<String> userName = new LinkedList<>();
            if (FlowNature.NodeStart.equals(custom.getType())) {
                UserEntity startUser = userList.stream().filter(t -> t.getId().equals(taskEntity.getCreatorUserId())).findFirst().orElse(null);
                userName.add(startUser != null ? startUser.getRealName() + "/" + startUser.getAccount() : "");
            } else if (FlowNature.NodeSubFlow.equals(custom.getType())) {
                List<UserEntity> list = new LinkedList<>();
                List<String> taskListAll = new ArrayList() {{
                    addAll(childNode.getCustom().getAsyncTaskList());
                    addAll(childNode.getCustom().getTaskId());
                }};
                List<String> taskUserList = childList.stream().filter(t -> taskListAll.contains(t.getId())).map(FlowTaskEntity::getCreatorUserId).collect(Collectors.toList());
                List<UserEntity> subFlowUserList = userList.stream().filter(t -> taskUserList.contains(t.getId())).collect(Collectors.toList());
                if (subFlowUserList.size() > 0) {
                    list.addAll(subFlowUserList);
                } else {
                    TaskChild taskChild = new TaskChild();
                    taskChild.setChildNode(childNode);
                    taskChild.setFlowTask(taskEntity);
                    taskChild.setEngine(engine);
                    taskChild.setFlowModel(flowModel);
                    taskChild.setVerify(false);
                    list.addAll(flowTaskUtil.childSaveList(taskChild));
                }
                List<String> nameList = new LinkedList<>();
                for (UserEntity entity : list) {
                    nameList.add(entity.getRealName() + "/" + entity.getAccount());
                }
                userName.addAll(nameList);
            } else if (FlowTaskOperatorEnum.FreeApprover.getCode().equals(type)) {
                List<String> operatorUserList = taskOperatorList.stream().filter(t -> t.getNodeCode().equals(custom.getNodeId()) && FlowNature.ParentId.equals(t.getParentId())).map(FlowTaskOperatorEntity::getHandleId).collect(Collectors.toList());
                List<UserEntity> userListAll = userList.stream().filter(t -> operatorUserList.contains(t.getId())).collect(Collectors.toList());
                List<String> nameList = new LinkedList<>();
                for (UserEntity operator : userListAll) {
                    nameList.add(operator.getRealName() + "/" + operator.getAccount());
                }
                userName.addAll(nameList);
            } else if (!FlowNature.NodeEnd.equals(custom.getNodeId())) {
                List<UserEntity> operatorUser = new LinkedList<>();
                List<String> list = nodeIdList.get(model.getId()) != null ? nodeIdList.get(model.getId()).stream().map(FlowTaskOperatorEntity::getHandleId).collect(Collectors.toList()) : new LinkedList<>();
                List<String> operUserAll = operatorNodeIdList.get(model.getId()) != null ? operatorNodeIdList.get(model.getId()).stream().map(FlowOperatorUserEntity::getHandleId).collect(Collectors.toList()) : new LinkedList<>();
                Set<String> userAll = new HashSet() {{
                    addAll(list);
                    addAll(operUserAll);
                }};
                if (userAll.size() > 0) {
                    operatorUser.addAll(userList.stream().filter(t -> userAll.contains(t.getId())).collect(Collectors.toList()));
                } else {
                    operatorUser.addAll(flowTaskUtil.operator(operatorList, taskOperator));
                }
                boolean isShow = true;
                //环节还没有经过和当前不显示审批人
                if (FlowTaskOperatorEnum.Tache.getCode().equals(type)) {
                    boolean completion = ("0".equals(model.getType()) || "1".equals(model.getType()));
                    if (!completion) {
                        isShow = false;
                    }
                }
                if (isShow) {
                    List<String> nameList = new LinkedList<>();
                    for (UserEntity operator : operatorUser) {
                        nameList.add(operator.getRealName() + "/" + operator.getAccount());
                    }
                    userName.addAll(nameList);
                }
            }
            model.setUserName(String.join(",", userName));
        }
        vo.setFlowTaskNodeList(flowTaskNodeListAll);
        //表单权限
        Properties approversProperties = new Properties();
        if (StringUtil.isNotEmpty(taskNodeId)) {
            FlowTaskNodeEntity taskNode = flowTaskNodeService.getInfo(taskNodeId);
            vo.setFormOperates(new ArrayList<>());
            if (taskNode != null) {
                ChildNodeList childNode = JsonUtil.getJsonToBean(taskNode.getNodePropertyJson(), ChildNodeList.class);
                approversProperties = childNode.getProperties();
                vo.setFormOperates(childNode.getProperties().getFormOperates());
            }
        }
        vo.setApproversProperties(approversProperties);
        //流程经办
        vo.setFlowTaskOperatorList(JsonUtil.getJsonToList(taskOperatorList, FlowTaskOperatorModel.class));
        //流程引擎
        vo.setFlowFormInfo(taskEntity.getFlowForm());
        //草稿数据
        if (StringUtil.isNotEmpty(taskOperatorId)) {
            FlowTaskOperatorEntity operator = taskOperatorList.stream().filter(t -> t.getId().equals(taskOperatorId)).findFirst().orElse(null);
            if (operator != null) {
                if (StringUtil.isNotEmpty(operator.getDraftData())) {
                    Map<String, Object> draftData = JsonUtil.stringToMap(operator.getDraftData());
                    draftData.put(versionKey, version);
                    vo.setDraftData(draftData);
                }
            }
        }
        //复活节点数据
        FlowTaskNodeEntity taskNode = taskNodeList.stream().filter(t -> t.getId().equals(taskEntity.getTaskNodeId())).findFirst().orElse(null);
        if (taskNode != null) {
            Map<String, Object> draftData = StringUtil.isEmpty(taskNode.getDraftData()) ? new HashMap<>() : JsonUtil.stringToMap(taskNode.getDraftData());
            draftData.put(versionKey, version);
            vo.setDraftData(draftData);
        }
        return vo;
    }

    @Override
    public List<FlowSummary> recordList(String id, String category, String type) {
        //审批汇总
        List<Integer> handleStatus = new LinkedList<>();
        if (!"0".equals(type)) {
            handleStatus.add(0);
            handleStatus.add(1);
        }
        List<FlowTaskOperatorRecordEntity> recordListAll = flowTaskOperatorRecordService.getRecordList(id, handleStatus);
        List<String> userIdAll = new LinkedList<>();
        List<String> userIdList = recordListAll.stream().map(FlowTaskOperatorRecordEntity::getHandleId).collect(Collectors.toList());
        List<String> operatorId = recordListAll.stream().filter(t -> StringUtil.isNotEmpty(t.getOperatorId())).map(FlowTaskOperatorRecordEntity::getOperatorId).collect(Collectors.toList());
        userIdAll.addAll(userIdList);
        userIdAll.addAll(operatorId);
        List<UserEntity> userList = serviceUtil.getUserName(userIdAll);
        List<FlowSummary> list = new LinkedList<>();
        Map<String, String> map = new HashMap<>();
        Map<String, List<FlowTaskOperatorRecordEntity>> operatorAll = new HashMap<>();
        if (FlowRecordListEnum.position.getCode().equals(category)) {
            List<String> userId = userList.stream().map(UserEntity::getId).collect(Collectors.toList());
            List<UserRelationEntity> relationList = serviceUtil.getListByUserIdAll(userId);
            List<String> objectId = relationList.stream().map(UserRelationEntity::getObjectId).collect(Collectors.toList());
            List<PositionEntity> positionListAll = serviceUtil.getPositionName(objectId);
            for (PositionEntity entity : positionListAll) {
                map.put(entity.getId(), entity.getFullName());
                List<String> userAll = relationList.stream().filter(t -> t.getObjectId().equals(entity.getId())).map(UserRelationEntity::getUserId).collect(Collectors.toList());
                List<FlowTaskOperatorRecordEntity> operator = new LinkedList<>();
                for (FlowTaskOperatorRecordEntity recordEntity : recordListAll) {
                    if (userAll.contains(recordEntity.getHandleId())) {
                        operator.add(recordEntity);
                    }
                }
                operatorAll.put(entity.getId(), operator);
            }
        } else if (FlowRecordListEnum.role.getCode().equals(category)) {
            List<String> userId = userList.stream().map(UserEntity::getId).collect(Collectors.toList());
            List<UserRelationEntity> relationList = serviceUtil.getListByUserIdAll(userId);
            List<String> objectId = relationList.stream().map(UserRelationEntity::getObjectId).collect(Collectors.toList());
            List<RoleEntity> roleListAll = serviceUtil.getListByIds(objectId);
            for (RoleEntity entity : roleListAll) {
                map.put(entity.getId(), entity.getFullName());
                List<String> userAll = relationList.stream().filter(t -> t.getObjectId().equals(entity.getId())).map(UserRelationEntity::getUserId).collect(Collectors.toList());
                List<FlowTaskOperatorRecordEntity> operator = new LinkedList<>();
                for (FlowTaskOperatorRecordEntity recordEntity : recordListAll) {
                    if (userAll.contains(recordEntity.getHandleId())) {
                        operator.add(recordEntity);
                    }
                }
                operatorAll.put(entity.getId(), operator);
            }
        } else if (FlowRecordListEnum.department.getCode().equals(category)) {
            List<String> organizeList = userList.stream().map(UserEntity::getOrganizeId).collect(Collectors.toList());
            List<OrganizeEntity> organizeListAll = serviceUtil.getOrganizeName(organizeList);
            for (OrganizeEntity entity : organizeListAll) {
                map.put(entity.getId(), entity.getFullName());
                List<String> userAll = userList.stream().filter(t -> t.getOrganizeId().equals(entity.getId())).map(UserEntity::getId).collect(Collectors.toList());
                List<FlowTaskOperatorRecordEntity> operator = new LinkedList<>();
                for (FlowTaskOperatorRecordEntity recordEntity : recordListAll) {
                    if (userAll.contains(recordEntity.getHandleId())) {
                        operator.add(recordEntity);
                    }
                }
                operatorAll.put(entity.getId(), operator);
            }
        }
        for (String key : map.keySet()) {
            String fullName = map.get(key);
            FlowSummary summary = new FlowSummary();
            summary.setId(key);
            summary.setFullName(fullName);
            List<FlowTaskOperatorRecordEntity> recordList = operatorAll.get(key);
            List<FlowSummary> childList = new LinkedList<>();
            for (FlowTaskOperatorRecordEntity entity : recordList) {
                FlowSummary childSummary = JsonUtil.getJsonToBean(entity, FlowSummary.class);
                UserEntity user = userList.stream().filter(t -> t.getId().equals(entity.getHandleId())).findFirst().orElse(null);
                childSummary.setUserName(user != null ? user.getRealName() + "/" + user.getAccount() : "");
                UserEntity userEntity = userList.stream().filter(t -> t.getId().equals(entity.getOperatorId())).findFirst().orElse(null);
                childSummary.setOperatorId(userEntity != null ? userEntity.getRealName() + "/" + userEntity.getAccount() : "");
                childList.add(childSummary);
            }
            summary.setList(childList);
            list.add(summary);
        }
        return list;
    }

    @Override
    public boolean press(String id, FlowModel flowModel) throws WorkFlowException {
        UserInfo userInfo = flowModel.getUserInfo();
        FlowTaskEntity flowTaskEntity = flowTaskService.getInfo(id);
        FlowEngineEntity engine = flowEngineService.getInfo(flowTaskEntity.getFlowId());
        List<FlowTaskOperatorEntity> operatorList = flowTaskOperatorService.press(id);
        boolean flag = operatorList.size() > 0;
        Map<String, Object> data = JsonUtil.stringToMap(flowTaskEntity.getFlowFormContentJson());
        List<FlowTaskNodeEntity> taskNodeList = flowTaskNodeService.getList(id);
        //发送消息
        FlowMsgModel flowMsgModel = new FlowMsgModel();
        flowMsgModel.setCirculateList(new ArrayList<>());
        flowMsgModel.setNodeList(taskNodeList);
        flowMsgModel.setOperatorList(operatorList);
        flowMsgModel.setTaskEntity(flowTaskEntity);
        flowMsgModel.setData(data);
        flowMsgModel.setEngine(engine);
        flowMsgModel.setTitle("已被【催办】");
        flowMsgModel.setFlowModel(flowModel);
//        flowMsgUtil.message(flowMsgModel);
        //定时器
        WorkJobModel workJobModel = new WorkJobModel(id, flowMsgModel, userInfo);
        WorkJobUtil.insertRedis(workJobModel, redisUtil);
        return flag;
    }

    @Override
    public FlowCandidateVO candidates(String id, FlowModel flowModel, boolean batch) throws WorkFlowException {
        FlowTaskOperatorEntity operator = flowTaskOperatorService.getOperatorInfo(id);
        List<ChildNodeList> childNodeListAll = flowTaskUtil.childNodeListAll(operator, flowModel);
        List<FlowCandidateListModel> listVO = new LinkedList<>();
        FlowCandidateVO vo = new FlowCandidateVO();
        boolean brachFlow = childNodeListAll.stream().filter(t -> t.getCustom().getBranchFlow()).count() > 0;
        int candidates = 0;
        for (ChildNodeList childNodeList : childNodeListAll) {
            Properties properties = childNodeList.getProperties();
            String nodeId = childNodeList.getCustom().getNodeId();
            String nodeName = properties.getTitle();
            String type = properties.getAssigneeType();
            FlowCandidateListModel candidateVO = new FlowCandidateListModel();
            candidateVO.setNodeName(nodeName);
            candidateVO.setNodeId(nodeId);
            boolean isCandidates = FlowTaskOperatorEnum.FreeApprover.getCode().equals(type);
            candidateVO.setIsCandidates(isCandidates);
            if (isCandidates) {
                List<String> list = new LinkedList<>();
                list.addAll(properties.getApproverPos());
                list.addAll(properties.getApproverRole());
                list.addAll(properties.getApproverOrg());
                list.addAll(properties.getApproverGroup());
                List<UserRelationEntity> listByObjectIdAll = serviceUtil.getListByObjectIdAll(list);
                List<String> userId = listByObjectIdAll.stream().map(UserRelationEntity::getUserId).collect(Collectors.toList());
                userId.addAll(properties.getApprovers());
                Pagination pagination = JsonUtil.getJsonToBean(flowModel, Pagination.class);
                List<UserEntity> userName = serviceUtil.getUserName(userId, pagination);
                candidateVO.setHasCandidates(userName.size() > 0);
            }
            candidates += isCandidates ? 1 : 0;
            listVO.add(candidateVO);
        }
        if (batch && brachFlow) {
            throw new WorkFlowException(MsgCode.WF124.get());
        }
        int flowType = brachFlow ? 1 : candidates > 0 ? 2 : 3;
        if (operator != null) {
            if (brachFlow) {
                List<FlowTaskOperatorEntity> operatorList = flowTaskOperatorService.getList(operator.getTaskId()).stream().filter(t -> t.getTaskNodeId().equals(operator.getTaskNodeId()) && FlowNodeEnum.Process.getCode().equals(t.getState()) && FlowNature.ParentId.equals(t.getParentId())).collect(Collectors.toList());
                operatorList.stream().forEach(t -> {
                    if (t.getId().equals(id)) {
                        t.setCompletion(FlowNature.AuditCompletion);
                    }
                });
                FlowCountersignModel countersign = new FlowCountersignModel();
                countersign.setTaskNodeId(operator.getTaskNodeId());
                countersign.setOperatorList(operatorList);
                boolean isCountersign = flowTaskUtil.isCountersign(countersign);
                flowType = isCountersign ? flowType : brachFlow ? 3 : candidates > 0 ? 2 : 3;
            }
            if (!FlowNature.ParentId.equals(operator.getParentId())) {
                flowType = 3;
            }
        }
        vo.setType(flowType);
        vo.setList(listVO);
        return vo;
    }

    @Override
    public List<FlowCandidateUserModel> candidateUser(String id, FlowModel flowModel) throws WorkFlowException {
        List<FlowCandidateUserModel> dataList = new LinkedList<>();
        FlowTaskOperatorEntity operator = flowTaskOperatorService.getOperatorInfo(id);
        List<ChildNodeList> childNodeListAll = flowTaskUtil.childNodeListAll(operator, flowModel);
        for (ChildNodeList childNodeList : childNodeListAll) {
            Properties properties = childNodeList.getProperties();
            List<String> list = new LinkedList<>();
            list.addAll(properties.getApproverPos());
            list.addAll(properties.getApproverRole());
            list.addAll(properties.getApproverOrg());
            list.addAll(properties.getApproverGroup());
            List<UserRelationEntity> listByObjectIdAll = serviceUtil.getListByObjectIdAll(list);
            List<String> userId = listByObjectIdAll.stream().map(UserRelationEntity::getUserId).collect(Collectors.toList());
            userId.addAll(properties.getApprovers());
            Pagination pagination = JsonUtil.getJsonToBean(flowModel, Pagination.class);
            List<UserEntity> userName = serviceUtil.getUserName(userId, pagination);
            flowModel.setTotal(pagination.getTotal());
            List<String> userIdAll = userName.stream().map(UserEntity::getId).collect(Collectors.toList());
            Map<String, List<UserRelationEntity>> userMap = serviceUtil.getListByUserIdAll(userIdAll).stream().filter(t -> PermissionConst.ORGANIZE.equals(t.getObjectType())).collect(Collectors.groupingBy(UserRelationEntity::getUserId));
            for (UserEntity entity : userName) {
                List<UserRelationEntity> listByUserId = userMap.get(entity.getId()) != null ? userMap.get(entity.getId()) : new LinkedList<>();
                StringJoiner joiner = new StringJoiner(",");
                for (UserRelationEntity relation : listByUserId) {
                    List<OrganizeEntity> organizeId = serviceUtil.getOrganizeId(relation.getObjectId());
                    if (organizeId.size() > 0) {
                        String organizeName = organizeId.stream().map(OrganizeEntity::getFullName).collect(Collectors.joining("/"));
                        joiner.add(organizeName);
                    }
                }
                FlowCandidateUserModel userModel = JsonUtil.getJsonToBean(entity, FlowCandidateUserModel.class);
                userModel.setFullName(entity.getRealName() + "/" + entity.getAccount());
                userModel.setHeadIcon(UploaderUtil.uploaderImg(entity.getHeadIcon()));
                userModel.setOrganize(joiner.toString());
                dataList.add(userModel);
            }
        }
        return dataList;
    }

    @Override
    @DSTransactional
    public void batch(FlowModel flowModel) throws WorkFlowException {
        List<String> idList = flowModel.getIds() != null ? flowModel.getIds() : new LinkedList<>();
        Integer batchType = flowModel.getBatchType();
        UserInfo userInfo = flowModel.getUserInfo();
        FlowContextHolder.initEvent();
        for (String id : idList) {
            String rejecttKey = userInfo.getTenantId() + id;
            if (redisUtil.exists(rejecttKey)) {
                throw new WorkFlowException(MsgCode.WF005.get());
            }
            redisUtil.insert(rejecttKey, id, 10);
            FlowTaskOperatorEntity operator = flowTaskOperatorService.getInfo(id);
            FlowTaskEntity taskEntity = flowTaskService.getInfo(operator.getTaskId());
            flowModel.setFormData(JsonUtil.stringToMap(taskEntity.getFlowFormContentJson()));
            switch (batchType) {
                case 0:
                    this.audit(id, flowModel);
                    break;
                case 1:
                    this.reject(id, flowModel);
                    break;
                case 2:
                    operator.setHandleId(flowModel.getFreeApproverUserId());
                    operator.setCreatorTime(new Date());
                    this.transfer(operator, flowModel);
                    break;
                default:
                    break;
            }
        }
        List<FlowParameterModel> parameterModels = FlowContextHolder.getAllEvent();
        for (FlowParameterModel model : parameterModels) {
            serviceUtil.infoToId(model.getInterId(), model.getParameterMap());
        }
        FlowContextHolder.clearEvent();
    }

    @Override
    public FlowCandidateVO batchCandidates(String flowId, String taskOperatorId, FlowModel flowModel) throws WorkFlowException {
        FlowEngineEntity flowEngine = flowEngineService.getInfo(flowId);
        FlowTaskOperatorEntity operator = flowTaskOperatorService.getInfo(taskOperatorId);
        FlowTaskNodeEntity taskNode = flowTaskNodeService.getInfo(operator.getTaskNodeId());
        FlowTaskEntity task = flowTaskService.getInfo(operator.getTaskId());
        ChildNode childNodeAll = JsonUtil.getJsonToBean(flowEngine.getFlowTemplateJson(), ChildNode.class);
        //获取流程节点
        List<ChildNodeList> nodeListAll = new LinkedList<>();
        List<ConditionList> conditionListAll = new LinkedList<>();
        //递归获取条件数据和节点数据
        FlowJsonUtil.getTemplateAll(childNodeAll, nodeListAll, conditionListAll);
        //判断节点是否有在条件中
        boolean isCondition = conditionListAll.stream().filter(t -> operator.getNodeCode().equals(t.getPrevId())).count() > 0;
        List<ChildNodeList> freeApprover = new LinkedList<>();
        List<ChildNodeList> branchFlow = new LinkedList<>();
        if (isCondition) {
            List<String> nodeNext = StringUtil.isNotEmpty(taskNode.getNodeNext()) ? Arrays.asList(taskNode.getNodeNext().split(",")) : new LinkedList<>();
            List<ChildNodeList> nextList = nodeListAll.stream().filter(t -> nodeNext.contains(t.getCustom().getNodeId())).collect(Collectors.toList());
            nextList.stream().forEach(t -> {
                if (FlowTaskOperatorEnum.FreeApprover.getCode().equals(t.getProperties().getAssigneeType())) {
                    freeApprover.add(t);
                }
                if (t.getCustom().getBranchFlow()) {
                    branchFlow.add(t);
                }
            });
        }
        if (freeApprover.size() > 0) {
            throw new WorkFlowException("条件流程包含候选人无法批量通过");
        }
        if (branchFlow.size() > 0) {
            throw new WorkFlowException(MsgCode.WF124.get());
        }
        Map<String, Object> objectMap = JsonUtil.stringToMap(task.getFlowFormContentJson());
        objectMap.put("flowId", task.getFlowId());
        flowModel.setFormData(objectMap);
        return candidates(taskOperatorId, flowModel, true);
    }

    @Override
    public void permissions(String userId, FlowTaskEntity flowTask, FlowTaskOperatorEntity operator, String msg, FlowModel flowModel) throws WorkFlowException {
        UserInfo userInfo = flowModel.getUserInfo();
        if (operator == null || FlowNodeEnum.Futility.getCode().equals(operator.getState()) || !FlowNature.ProcessCompletion.equals(operator.getCompletion())) {
            throw new WorkFlowException(StringUtil.isEmpty(msg) ? MsgCode.WF122.get() : msg);
        }
        List<String> flowDelegateList = flowDelegateService.getUser(userInfo.getUserId(), flowTask.getFlowId(), userId).stream().map(FlowDelegateEntity::getFTouserid).collect(Collectors.toList());
        flowDelegateList.add(userId);
        if (!flowDelegateList.contains(userInfo.getUserId())) {
            throw new WorkFlowException(MsgCode.WF122.get());
        }
        if (FlowTaskStatusEnum.Cancel.getCode().equals(flowTask.getStatus())) {
            throw new WorkFlowException(MsgCode.WF121.get());
        }
        if (FlowTaskStatusEnum.Revoke.getCode().equals(flowTask.getStatus())) {
            throw new WorkFlowException(MsgCode.WF120.get());
        }
    }

    @Override
    @DSTransactional
    public void change(FlowModel flowModel) throws WorkFlowException {
        UserInfo userInfo = flowModel.getUserInfo();
        FlowTaskEntity flowTask = flowTaskService.getInfo(flowModel.getTaskId());
        List<String> thisStepId = Arrays.asList(flowTask.getThisStepId().split(","));
        FlowTaskNodeEntity taskNodeEntity = flowTaskNodeService.getInfo(flowModel.getTaskNodeId());
        FlowEngineEntity engine = flowEngineService.getInfo(flowTask.getFlowId());
        boolean resurgence = flowModel.getResurgence();
        if (resurgence) {
            flowTask.setTaskNodeId(flowModel.getTaskNodeId());
            flowTask.setParentId(FlowNature.ParentId);
            flowTask.setStatus(FlowNature.NodeStart.equals(taskNodeEntity.getNodeType()) ? FlowTaskStatusEnum.Draft.getCode() : FlowTaskStatusEnum.Handle.getCode());
            if (StringUtil.isEmpty(taskNodeEntity.getDraftData())) {
                throw new WorkFlowException("该节点没有数据,无法复活");
            }
        }
        //获取节点
        List<FlowTaskNodeEntity> taskNodeListAll = flowTaskNodeService.getList(flowModel.getTaskId());
        List<FlowTaskNodeEntity> taskNodeList = taskNodeListAll.stream().filter(t -> FlowNodeEnum.Process.getCode().equals(t.getState())).collect(Collectors.toList());
        //当前节点是子流程不能变更
        List<FlowTaskNodeEntity> thisTaskNodeList = taskNodeList.stream().filter(t -> thisStepId.contains(t.getNodeCode())).collect(Collectors.toList());
        boolean isChild = thisTaskNodeList.stream().filter(t -> FlowNature.NodeSubFlow.equals(t.getNodeType())).count() > 0;
        if (isChild) {
            throw new WorkFlowException("当前节点有子流程无法变更");
        }
        ChildNodeList childNode = JsonUtil.getJsonToBean(taskNodeEntity.getNodePropertyJson(), ChildNodeList.class);
        flowTaskNodeService.update(taskNodeEntity);
        String nodeId = childNode.getCustom().getNodeId();
        String title = childNode.getProperties().getTitle();
        flowTask.setThisStepId(taskNodeEntity.getNodeCode());
        flowTask.setThisStep(taskNodeEntity.getNodeName());
        Integer progress = childNode.getProperties().getProgress() != null ? Integer.valueOf(childNode.getProperties().getProgress()) : null;
        flowTask.setCompletion(progress);
        flowTaskService.update(flowTask);
        //获取节点
        List<String> id = taskNodeList.stream().map(t -> t.getId()).collect(Collectors.toList());
        flowCandidatesService.deleteTaskNodeId(id);
        flowTaskNodeService.updateCompletion(id, FlowNature.AuditCompletion);
        List<FlowTaskNodeEntity> nextTaskNodeList = taskNodeList.stream().filter(t -> thisStepId.contains(t.getNodeCode())).collect(Collectors.toList());
        for (FlowTaskNodeEntity nodeEntity : nextTaskNodeList) {
            flowTaskUtil.change(taskNodeList, nodeEntity, false, FlowNature.AuditCompletion, flowModel);
            if (FlowNature.NodeSubFlow.equals(nodeEntity.getNodeType())) {
                ChildNodeList nodeModel = JsonUtil.getJsonToBean(nodeEntity.getNodePropertyJson(), ChildNodeList.class);
                List<String> idAll = nodeModel.getCustom().getTaskId();
                flowTaskService.deleteChildAll(idAll);
            }
        }
        if (taskNodeEntity != null) {
            flowTaskUtil.change(taskNodeList, taskNodeEntity, resurgence, FlowNature.ProcessCompletion, flowModel);
            taskNodeEntity.setCompletion(FlowNature.ProcessCompletion);
            flowTaskNodeService.update(taskNodeEntity);
        }
        Set<String> rejectNodeList = taskNodeList.stream().map(t -> t.getId()).collect(Collectors.toSet());
        flowTaskOperatorService.updateReject(flowModel.getTaskId(), rejectNodeList);
        flowOperatorUserService.updateReject(flowModel.getTaskId(), rejectNodeList);
        Set<String> recordNodeList = new HashSet<>();
        List<String> delTaskNode = new ArrayList() {{
            add(flowModel.getTaskNodeId());
        }};
        flowTaskUtil.upAll(recordNodeList, delTaskNode, taskNodeList);
        flowTaskOperatorRecordService.updateStatus(recordNodeList, flowTask.getId());
        List<FlowTaskOperatorEntity> operatorList = new LinkedList<>();
        List<ChildNodeList> nextOperatorList = new LinkedList<>();
        nextOperatorList.add(childNode);
        flowModel.setFormData(JsonUtil.stringToMap(flowTask.getFlowFormContentJson()));
        flowModel.setHandleOpinion(flowModel.getHandleOpinion());
        //查询审批人
        TaskOperator taskOperator = new TaskOperator();
        taskOperator.setChildNode(childNode);
        taskOperator.setTaskNodeList(taskNodeList);
        taskOperator.setTaskEntity(flowTask);
        taskOperator.setFlowModel(flowModel);
        taskOperator.setId(flowModel.getOperatorId());
        taskOperator.setUserInfo(userInfo);
        //插入新的候选人
        List<String> userIdAll = flowTaskUtil.userListAll(taskOperator);
        Map<String, List<String>> candidateErrorList = flowModel.getErrorRuleUserList() != null ? flowModel.getErrorRuleUserList() : new HashMap<>();
        for (String key : candidateErrorList.keySet()) {
            userIdAll.addAll(candidateErrorList.get(key));
        }
        List<UserEntity> userList = serviceUtil.getUserName(userIdAll, true);
        if (userList.size() == 0) {
            List<FlowErrorModel> errorList = new ArrayList() {{
                FlowErrorModel errorModel = new FlowErrorModel();
                errorModel.setNodeId(nodeId);
                errorModel.setNodeName(title);
                add(errorModel);
            }};
            throw new WorkFlowException(200, JsonUtil.getObjectToString(errorList));
        }
        for (int i = 0; i < userList.size(); i++) {
            UserEntity userEntity = userList.get(i);
            TaskOperatoUser taskOperatoUser = new TaskOperatoUser();
            taskOperatoUser.setDate(new Date());
            taskOperatoUser.setChildNode(childNode);
            taskOperatoUser.setAutomation("");
            taskOperatoUser.setId(FlowNature.ParentId);
            taskOperatoUser.setHandLeId(userEntity.getId());
            taskOperatoUser.setSortCode(i + 1);
            flowTaskUtil.operatorUser(operatorList, taskOperatoUser);
        }
        Map<String, List<FlowTaskOperatorEntity>> operatorMap = operatorList.stream().collect(Collectors.groupingBy(FlowTaskOperatorEntity::getTaskNodeId));
        for (ChildNodeList childNodeList : nextOperatorList) {
            Properties properties = childNodeList.getProperties();
            boolean counterSign = FlowNature.ImproperApprover.equals(properties.getCounterSign());
            if (counterSign && StringUtil.isEmpty(flowModel.getFreeApproverUserId())) {
                List<FlowTaskOperatorEntity> listAll = operatorMap.get(childNodeList.getTaskNodeId()) != null ? operatorMap.get(childNodeList.getTaskNodeId()) : new LinkedList<>();
                flowOperatorUserService.create(JsonUtil.getJsonToList(listAll, FlowOperatorUserEntity.class));
            }
        }
        //过滤依次审批人
        flowTaskUtil.improperApproverUser(operatorList, taskNodeList, childNode, null);
        flowTaskOperatorService.create(operatorList);
        //修改节点的选择分支数据
        recordNodeList.removeAll(delTaskNode);
        flowTaskNodeService.updateTaskNodeCandidates(new ArrayList<>(recordNodeList));
        //自动审批
        FlowApproveModel approveModel = FlowApproveModel.builder().operatorList(operatorList).taskNodeList(taskNodeList).flowTask(flowTask).flowModel(flowModel).build();
        flowTaskUtil.approve(approveModel);
        //审批数据赋值
        FlowTaskOperatorRecordEntity operatorRecord = new FlowTaskOperatorRecordEntity();
        FlowTaskOperatorEntity operator = new FlowTaskOperatorEntity();
        operator.setTaskId(flowTask.getId());
        operator.setHandleId(userInfo.getUserId());
        operator.setNodeCode(taskNodeEntity.getNodeCode());
        operator.setNodeName(taskNodeEntity.getNodeName());
        FlowOperatordModel flowOperatordModel = new FlowOperatordModel();
        flowOperatordModel.setStatus(resurgence ? FlowRecordEnum.resurrection.getCode() : FlowRecordEnum.change.getCode());
        flowOperatordModel.setFlowModel(flowModel);
        flowOperatordModel.setUserId(userInfo.getUserId());
        flowOperatordModel.setOperator(operator);
        flowOperatordModel.setOperatorId(operator.getHandleId());
        flowTaskUtil.operatorRecord(operatorRecord, flowOperatordModel);
        flowTaskOperatorRecordService.create(operatorRecord);
        //发送消息
        FlowMsgModel flowMsgModel = new FlowMsgModel();
        flowMsgModel.setNodeList(taskNodeList);
        flowMsgModel.setOperatorList(operatorList);
        flowMsgModel.setCirculateList(new ArrayList<>());
        flowMsgModel.setData(flowModel.getFormData());
        flowMsgModel.setTaskNodeEntity(null);
        flowMsgModel.setTaskEntity(flowTask);
        flowMsgModel.setFlowModel(flowModel);
        flowMsgModel.setEngine(engine);
//        flowMsgUtil.message(flowMsgModel);
        //定时器
        WorkJobModel workJobModel = new WorkJobModel(flowModel.getTaskNodeId(), flowMsgModel, userInfo);
        WorkJobUtil.insertRedis(workJobModel, redisUtil);
        //超时
        for (FlowTaskOperatorEntity operatorOne : operatorList) {
            WorkTimeoutJobModel workTimeoutJobModel = WorkTimeoutJobModel.builder().flowModel(flowModel)
                    .taskId(flowTask.getId()).taskNodeId(operatorOne.getTaskNodeId()).taskNodeOperatorId(operatorOne.getId()).operatorEntity(operatorOne)
                    .tenantId(userInfo.getTenantId()).tenantDbConnectionString(userInfo.getTenantDbConnectionString()).build();
            workTimeoutJobUtil.insertRedis(workTimeoutJobModel, redisUtil);
        }
    }

}
